我用多个JOIN
(包括一个LEFT JOIN
)编写了这个SQL请求。
- 它提供了预期的结果**。
SELECT DISTINCT c.Id,
c.Title,
COUNT(v.Id) AS 'Nb_V2',
COUNT(DISTINCT v.IdUser) AS 'Nb_V1',
r.cnt AS 'Nb_R'
FROM TABLE_C c
JOIN TABLE_V v on c.Id = v.Id
LEFT JOIN (
SELECT Id, COUNT(*) AS cnt
FROM TABLE_R
GROUP BY Id
) r ON c.Id = r.Id
WHERE c.IdUser = '1234'
GROUP BY c.Id, c.Title, r.cnt
然而,我希望这个请求的Linq等价物,把它放在我的应用程序的数据访问层。
我试过这样的方法:
var qResult = from c in dbContext.TABLE_C
join v in dbContext.TABLE_V on c.IdC equals v.IdC
join r in dbContext.TABLE_R on v.IdC equals r.IdC into temp
from x in temp.DefaultIfEmpty()
group x by new { c.IdC, c.Title /*miss something ?*/} into grouped
select new
{
IdC = grouped.Key.IdC, --good result
Title = grouped.Key.Title, --good result
NbR = grouped.Distinct().Count(t => t.IdC > 0), --good, but "t.Id > 0" seems weird
Count = --I'm lost. No idea how to get my COUNT(...) properties (Nb_V1 and Nb_V2)
};
我尝试修改this SO question,但无法解决。我对分组子请求中的Count
感到困惑。
谁能解释一下我哪里错了?
专业提示:如果有人能用lambda表达式写出等价的表达式,那就加分了
2条答案
按热度按时间fae0ux8s1#
要将SQL转换为LINQ查询解析:
1.将子选择转换为单独声明的变量 *,除非它们引用子选择 * 外部的列,在这种情况下,使用括号创建子查询。
1.按照LINQ子句顺序翻译每个子句,将一元和聚合运算符(
DISTINCT
、TOP
、MIN
、MAX
等)翻译为应用于整个LINQ查询的函数。1.使用表别名作为范围变量。使用列别名作为匿名类型字段名。
1.对多个列使用匿名类型(
new {
...}
)(例如在groupby
中)。1.使用
First().field
从groupby
聚合范围变量获取非键值。1.使用EF或EF Core时,可能使用
.Include()
将JOIN
子句转换为导航属性。1.否则,作为两个表之间的多个
AND
艾德相等测试的JOIN
子句应转换为equals
每一端的匿名对象。JOIN
条件如果不都是使用AND
进行的相等性测试,则必须使用连接外部的where
子句或使用叉积来处理(from
...from
...),然后是where
。如果您正在执行LEFT JOIN
,在连接范围变量和DefaultIfEmpty()
调用之间添加一个lambdaWhere
子句。1.通过使用
into
joinvariable 并执行另一个from
(joinvariable 后跟.DefaultIfEmpty()
)来模拟LEFT JOIN
。1.将
FROM
子句中的多个表转换为多个from
子句。1.将
FROM T1 CROSS APPLY T2
转换为两个from
子句,一个用于T1
,另一个用于T2
。1.将
FROM T1 OUTER APPLY T2
转换为两个from
子句,一个用于T1
,另一个用于T2
,但将.DefaultIfEmpty()
添加到T2
。1.将
COALESCE
替换为条件运算符(?:
)和null
测试。1.使用常量列表的文本数组或数组变量,将
IN
转换为.Contains()
,将NOT IN
转换为!
...Contains()
。1.将 x
BETWEEN
* 低 *AND
* 高 * 转换为 * 低 *<=
x&&
x<=
* 高 *。1.将
CASE
、ISNULL
和IIF
转换为三元条件运算符?:
。SELECT *
必须替换为select range_variable,对于连接,则为包含所有范围变量的匿名对象。SELECT
列必须替换为select new {
...}
,从而创建一个包含所有所需字段或表达式的匿名对象。1.通过重复表达式或在首次使用表达式之前使用
let
命名表达式,可以转换对计算SELECT
列的引用。1.正确的
FULL OUTER JOIN
必须用extension method处理。1.将
UNION
转换为Concat
,除非两个子查询都是DISTINCT
,在这种情况下,您可以转换为Union
,而忽略DISTINCT
。1.使用单例
GroupBy
转换没有GROUP BY
的聚合查询:添加.GroupBy(r => 1)
,然后转换Select
中的聚合函数。1.日期数学和其他一些canonical函数可以使用
EF.Functions
来访问,以获取DbFunctions
类(EF Core)、EntityFunctions
类(EF〈6)或DbFunctions
的示例来访问静态方法(EntityFramework 6.x)。1.使用(EF核心〉= 2)
EF.Functions.Like(column, pattern)
或(EF 6.x)DbFunctions.Like(column, pattern)
转换SQLLIKE
表达式。将这些规则应用于SQL查询,您将获得:
lambda转换很复杂,但是需要将
LEFT JOIN
转换为GroupJoin
...SelectMany
:kb5ga3dv2#
使用LINQ Me Up的(正在开发的)版本:我正在开发的一个人工智能支持的SQL到LINQ转换工具,答案是: