c# - 使 Linq to Sql 使用 ISNULL 而不是 COALESCE 生成 T-SQL

标签 c# linq tsql linq-to-sql

我有一个 linq to sql 查询,它返回一些余额非零的订单(事实上,查询有点复杂,但为了简单起见,我省略了一些细节)。这个查询也应该返回没有 CardItems 的订单(在 T-SQL 中两个子查询都返回 NULL,并且比较两个 NULLS 给出 FALSE,所以我将子查询的 NULL 结果值转换为 0 以进行比较)。

var q = (from o in db.Orders
         where db.Cards(p =>
             p.OrderId == o.Id 
             && p.Sum + (db.CardItems.Where(i => i.IncomeId == p.Id)
                        .Sum(i => (double?)i.Amount) ?? 0) 
                    != (db.CardItems.Where(i => i.DeductId == p.Id)
                        .Sum(i => (double?)i.Amount) ?? 0)
            ).Any()
         select o);

问题是,转换表达式 Sum(i => (double?)i.Amount) ?? 0 produce COALESCE 运算符,这比将 COALESCE 替换为 ISNULL 的完全相同的 T-SQL 查询慢十倍,因为其中包含子查询。在这种情况下是否有可能生成 ISNULL?

最佳答案

根据我的经验,让 linq 生成您想要的 SQL 充其量是一件麻烦事。如果您有一个比 linq 更好的查询实现(工作正常且性能良好),请继续使用它,即使只是针对这个查询也是如此。

最快的方法可能是使用 DataContext.ExecuteQuery<TResult> .它甚至会为您组合和处理返回的对象,就像 linq 自己生成查询一样。

http://msdn.microsoft.com/en-us/library/bb361109.aspx

很多人宁愿把这个 SQL 放在存储过程中,尤其是在生产代码中。然后你只需要将存储过程映射到你的 linq 对象中,它的工作方式是一样的。通常情况下,ScottGu 有一篇关于如何做到这一点的相当详细的帖子:

http://weblogs.asp.net/scottgu/archive/2007/08/16/linq-to-sql-part-6-retrieving-data-using-stored-procedures.aspx

关于c# - 使 Linq to Sql 使用 ISNULL 而不是 COALESCE 生成 T-SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10948219/

相关文章:

mysql - 有人会如何为 SQL 创建 ID?

sql-server - T-SQL Cross Join 获取缺失值

SQL Server : Optional variable in a stored procedure

c# - 实时更新 .NET 桌面应用程序

C# 定时器不工作

c# - 未在 C# 中设置对象属性

c# - LINQ 选择列表,其中子列表包含另一个列表中的项目

c# - 空条件运算符为事件抛出空引用

c# - 通过 switch 语句处理对象集合

sql-server - MVC 4 中下拉列表的 Optgroup