消除 LET 运算符和 SqlFunctions

Posted

技术标签:

【中文标题】消除 LET 运算符和 SqlFunctions【英文标题】:Eliminate LET operator and SqlFunctions 【发布时间】:2018-10-23 02:02:42 【问题描述】:

请考虑这个查询:

from r in ent.MyTable
group r by new  r.EmployeeName, r.EmployeeID  into g
let c = " (" + SqlFunctions.StringConvert((decimal?)g.Count()) + " )"
select new

    EmployeeName = g.Key.EmployeeName + c ,
    EmployeeID = g.Key.EmployeeID
);

效果很好。当我想改用这个查询时,我得到一个错误:

from r in ent.MyTable
group r by new  r.EmployeeName, r.EmployeeID  into g
select new

    EmployeeName = g.Key.EmployeeName + " (" + g.Count() + ")",
    EmployeeID = g.Key.EmployeeID
);

错误:

无法将 System.Object 转换为 System.String

我该怎么做?

【问题讨论】:

添加:g.Count().ToString() @jdweng ToString 不是 SQL Server 函数 是 linq。但是 g.Count() 是一个整数,需要将其转换为字符串。 您使用的是哪个 EF 版本?所需的语法完美适用于 EF6.2 另一个想法:如果您选择了EmployeeNameEmployeeIDCount,然后只将员工姓名和计数组合成一个字符串,那会怎样。是在前端层中,还是在视图中(如果这是 MVC 应用程序)?然后在查询中构造显示字符串可能会更干净。 【参考方案1】:

为什么不对输出进行双重转换?

from r in ent.MyTable
group r by new  r.EmployeeName, r.EmployeeID  into g
select new

    EmployeeName = g.Key.EmployeeName,
    Count = g.Count(),
    EmployeeID = g.Key.EmployeeID

into tmp
select new

    EmployeeName = tmp.EmployeeName + "(" + Count + ")",
    EmployeeID = tmp.EmployeeID

【讨论】:

这类似于let 运算符在 OP 查询中所做的,他们希望避免。 我认为查询性能可能是避免原始查询中的 let 的原因,这就是我对行执行两次转换的原因。如果不是这样,那么我的答案可能不适用。 但是,即使我的答案中的查询看起来很相似,它也会产生完全不同的 SQL。【参考方案2】:

所以你有一个MyTable,其中表中的每一行(可能是员工)至少有属性EmployeeIdEmployeeName

您希望将表中的行分组为具有相同 EmployeeIdEmployeeName 的组。从每个组中,您需要共同的EmployeeId 和该组中的员工人数,形式为共同的“员工姓名”+ 员工人数。

var result = ent.MyTable                   // take MyTable
   .GroupBy(employee => new                // group all rows of this table into groups
                                          // with equal EmployeeId and EmployeeName
       Id = employee.EmployeeId,
       Name = employee.EmployeeName,
   )
   .Select(group => new                    // from every group make one object
                                          // with properties:
       EmployeeId = group.Key.Id,          // - the common employeeId
       EmployeeName = group.Key.Name       // - the common employeeName + the string value 
           + group.Count().ToString(),     //   of the number of elements in the group
   );

【讨论】:

以上是关于消除 LET 运算符和 SqlFunctions的主要内容,如果未能解决你的问题,请参考以下文章

是否有可能包括SqlFunctions.StringConvert在Lambda表达式?

为啥不能使用 SqlFunctions 在 LinQ 中将 int 转换为字符串?

SQL高级查询基础

java四则运算

了解let

一个可以为多个构造函数消除 0 (NULL) 的歧义吗?和赋值运算符?