【问题标题】:Complex LINQ query from SQL query来自 SQL 查询的复杂 LINQ 查询
【发布时间】:2011-05-15 08:22:26
【问题描述】:

我有一个 SQL 查询:

 SELECT Sum(ABS([Minimum Installment])) AS SumOfMonthlyPayments FROM tblAccount 
        INNER JOIN tblAccountOwner ON tblAccount.[Creditor Registry ID] = tblAccountOwner.
        [Creditor Registry ID] AND tblAccount.[Account No] = tblAccountOwner.[Account No] 
        WHERE (tblAccountOwner.[Account Owner Registry ID] = 731752693037116688) 
        AND (tblAccount.[Account Type] NOT IN ('CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04')) 
        AND (DATEDIFF(mm, tblAccount.[State Change Date], GETDATE()) <= 
        6 OR tblAccount.[State Change Date] IS NULL)
        AND (tblAccount.[Account Status ID] <> 999)
        AND ((tblAccount.[Account Type] NOT IN ('CL01','PL01','CL10','
        CL11','PL10','PL11','OD','CL00','PL00','CL03','CL20','CL30','CL31','CL32',
        'CL33','CL34','CL35','CL69','CL90','ML00','PL03','PL20','PL30','PL31','PL33',
        'CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04',
        'PL34','PL35','PL40','PL90')) 
        AND NOT CONTAINS(tblAccount.[Account Type], 'Overdra') 
        OR NOT CONTAINS(tblAccount.[Account Type], 'Mortgage') 
        OR NOT CONTAINS(tblAccount.[Account Type],'Revolv') 
        OR NOT CONTAINS(tblAccount.[Account Type],'*Credit*Card*'))

我已经把它翻译成 LINQ:

var excludeTypes = new[]
               {
                  "CA00", "CA01", "CA03", "CA04", "CA02",
                    "PA00", "PA01", "PA02", "PA03", "PA04"      
               };

            var maxStateChangeMonth = 4;
            var excludeStatusId = 999;
            var includOtherPayments = new[] {
                        "CL01","PL01","CL10",
                        "CL11","PL10","PL11","OD","CL00","PL00","CL03","CL20","CL30",
                        "CL31","CL32,CL33","CL34","CL35","CL69","CL90","ML00","PL03",
                        "PL20","PL30","PL31","PL33,CA00", "CA01", "CA03", "CA04","CA02",
                        "PA00", "PA01", "PA02", "PA03", "PA04,PL34","PL35","PL40","PL90" 
                    };

            var sum = (
               from account in context.Accounts
               from owner in account.AccountOwners
               where owner.AccountOwnerRegistryId == ownerRegistryId
               where !excludeTypes.Contains(account.AccountType)
               where account.StateChangeDate == null
               ||
                   EntityFunctions.DiffMonths(account.StateChangeDate, DateTime.Now)
                       <= maxStateChangeMonth
               where includOtherPayments.Contains(account.AccountType) ||
                       !account.AccountType.Contains("Overdra") || !account.AccountType.Contains("Mortgage")
                       || !account.AccountType.Contains("Revolv") || !account.AccountType.Contains("*Credit*Card*")
               where account.AccountStatusId != excludeStatusId
               select (decimal?)account.MinimumInstallment).ToList()
               .Sum(minimumInstallment => Math.Abs((decimal)(minimumInstallment)));

            return sum;

但是 SQL 返回 0 而 LINq 返回 23456。我知道问题在于 LINQ 中的括号或 where 语句的顺序。请建议我解决方案。

【问题讨论】:

    标签: sql linq linq-to-entities


    【解决方案1】:

    您可以尝试将您的 LINQ 查询放入 LINQPad。这是一个有用的免费工具,它将向您展示 LINQ 查询生成的原始 SQL 以帮助您调试它。它适用于 LINQ-to-SQL 和实体框架查询。

    【讨论】:

    • 我使用了 LINQPAD,但我不能在这个查询中使用它,因为我在这个查询中使用的是实体而不是表名。
    • 唯一的问题是 where 语句的括号或顺序。
    【解决方案2】:

    乍一看主要区别是: - SQL 查询中的 FTS 函数contains - LINQ 查询中的方法Contains(翻译为like,而不是FTS 调用)

    如果您想使用 FTS - 您应该使用表值函数 (TVF) 或存储过程 (SP)。还有一些其他选项(例如,ExecuteQuery),但我觉得它们不方便。

    【讨论】:

      猜你喜欢
      • 2018-02-08
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-18
      • 1970-01-01
      相关资源
      最近更新 更多