【问题标题】:Linq to Entities using incorrect parametersLinq to Entities 使用不正确的参数
【发布时间】:2012-08-16 19:10:21
【问题描述】:

我已经为此工作了将近 9 个小时,只是不明白发生了什么。我创建了一个高级查询生成器,允许用户将部分添加到他们的 where 子句中。我的计划是利用延迟执行。问题是我一直得到 0 作为我知道有记录的东西的计数。更令人费解的是,只有在我有超过 1 个查询时才会发生这种情况。因为我不能给你我的数据模型和我所有的代码,所以我总结了一下,这里是一个基本的代码示例:

        string foo = "smith";
        var result = context.claims.AsQueryable();
        var temp = from p in result
                   where p.Prescription.Patient.last_name.Contains(foo)
                   select p;
        foo = "jo";
        temp = from p in temp
               where p.Prescription.Patient.first_name.Contains(foo)
               select p;
        int count = temp.Count();

现在,我的期望是,这会给我一个返回结果的查询,其中患者的姓氏类似于“%smith%”,名字类似于“%jo%”。然而,这里是执行的查询:

    exec sp_executesql N'SELECT 
[GroupBy1].[A1] AS [C1]
FROM ( SELECT 
    COUNT(1) AS [A1]
    FROM     [dbo].[claim] AS [Extent1]
    INNER JOIN [dbo].[Prescription] AS [Extent2] ON [Extent1].[prescriptionId] = [Extent2].[id]
    LEFT OUTER JOIN [dbo].[Patient] AS [Extent3] ON [Extent2].[patient_id] = [Extent3].[id]
    LEFT OUTER JOIN [dbo].[Prescription] AS [Extent4] ON [Extent1].[prescriptionId] = [Extent4].[id]
    LEFT OUTER JOIN [dbo].[Patient] AS [Extent5] ON [Extent4].[patient_id] = [Extent5].[id]
    WHERE ([Extent3].[last_name] LIKE @p__linq__0 ESCAPE N''~'') AND ([Extent5].[first_name] LIKE @p__linq__1 ESCAPE N''~'')
)  AS [GroupBy1]',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',**@p__linq__0=N'%jo%',@p__linq__1=N'%jo%**'

从执行的查询可以看出,我没有得到预期的结果。相反,它将 linq 查询上的两个参数都设置为变量的最后一个值。

有人能解释一下为什么会这样吗?我找到了一种解决方法,但它并不漂亮。我必须为每个可能的列声明一个变量并将该变量 = 设置为该值,然后在 linq 语句中使用该变量:

        string foo = "smith", foo2 = "jo";
        var result = context.claims.AsQueryable();
        var temp = from p in result
                   where p.Prescription.Patient.last_name.Contains(foo)
                   select p;
        temp = from p in temp
               where p.Prescription.Patient.first_name.Contains(foo2)
               select p;
        int count = temp.Count();

【问题讨论】:

  • 因为执行被延迟,查询表达式直到你实际枚举结果(Count())时才被翻译。此时,foo 的值为“jo”。
  • 感谢 Wiktor 的快速回复!嗯,这是有道理的,但它确实会导致我的逻辑出现问题!我不敢相信我找不到其他看过这个的人。
  • 十分钟后,您找到了看到它的@WiktorZychla。将两个不同的字符串作为两个不同的字符串有什么“不漂亮”?
  • 拥有 2 个字符串的问题在于,在现实世界中,我希望有 N 个列进行搜索,并且我试图创建一个可以动态添加子句的函数。但是,如果我必须知道有多少子句,那么它会降低动态性和硬编码。
  • 使用你对一个接一个代码块采取的方法,无论如何你必须知道这一点,所以你写出那么多块。使用真正的代码,您要么需要某种可枚举、列表、数组等,要么多次调用刚刚添加一个的函数,这样就不会有问题了。

标签: c# linq entity-framework linq-to-entities


【解决方案1】:
int count = result.Count(x=> x.Prescription.Patient.last_name.Contains(foo) && 
                             x.Prescription.Patient.first_name.Contains(foo2));

var result = (from p in result
              where (p.Prescription.Patient.last_name.Contains(foo) && 
                     p.Prescription.Patient.first_name.Contains(foo2))
              select p).Count();

还可以看看使用PredicateBuidler 动态组合表达式谓词。如果您需要动态构建混合 && 和 || 的复杂查询,它会很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2019-02-01
    相关资源
    最近更新 更多