LINQ和SQL中看似等效的查询会返回不同的结果

时间:2015-11-07 13:32:23

标签: c# sql entity-framework linq join

不确定为何将其作为欺骗手段进行链接。问题是不同的。答案是不同的。不知道该改变什么。如果有人看到我遗失的内容,请告诉我......

我使用这两个查询获得了不同数量的结果。在分析了几个小时之后,我需要放弃,承认我无法发现重要性的差异。由于我的方法库已被清空,我正在寻求帮助。

LINQ

List<Uno> result = context.Unos
  .Join(context.Duos, uno => uno.CommonId, duo => duo.CommonId,
    (uno, duo) => new { Uno = uno, Duo = duo })
  .Where(item => item.Uno.Amount > 0
    && item.Duo.Type == 2)
  .Select(item => item.Uno)
  .ToList();

SQL

select * from Uno as u
join Duo as d on d.CommonId = u.CommonId
where u.Amount > 0
  and d.Type = 2

问题一是如果上述两个陈述确实相同或者我错过了什么。问题二是我缺少的(如果有的话)或如何解决它(如果我不是)。

  1. 对同一个数据库进行调用。
  2. 结果数量大相径庭(142和1437)。
  3. 为内连接提取相同的结果集。
  4. Uno Duo 都是视图,而不是表格。
  5. 我还可以验证哪些内容?

    修改

    在社区获得了一些非常好的支持后,我们确定LINQ查询可以通过以下命令进行SQL查询。

    var wtd = context.Unos
      .Join(context.Duos, uno => uno.CommonId, duo => duo.CommonId,
        (uno, duo) => new { Uno = uno, Duo = duo })
      .Where(item => item.Uno.Amount > 0
        && item.Duo.Type == 2)
      .Select(item => item.Uno)
      .ToString();
    

    疯狂的是,在SQL Manager中执行那个字符串会产生142个结果(就像上面的例子中的查询一样,SQL版本),它与它的差别很小。但是,执行LINQ查询本身会产生1437个结果。我甚至开始哭泣太困惑了......

      

    &#34; SELECT \ r \ n [Extent1]。[CommonId] AS [CommonId],\ r \ n [Extent1]。[X] AS [X] \ r \ n FROM(SELECT \ n [Uno] ]。[CommonId] AS [CommonId],\ n [Uno]。[X] AS [X] \ n FROM [财务]。[Uno] AS [Uno])AS [Extent1] \ r \ n INNER JOIN(SELECT \ n [Duo]。[CommonId] AS [CommonId],\ n [Duo]。[Y] AS [Y],\ n [Duo]。[Z] AS [Z],\ n [Duo]。[Type] ] AS [类型],\ n [Duo]。[U] AS [U],\ n [Duo]。[V] AS [V] \ n FROM [财务]。[Duo] AS [Duo])AS [ Extent2] ON [Extent1]。[CommonId] = [Extent2]。[CommonId] \ r \ n WHERE([Extent1]。[X]&gt; cast(0 as decimal(18)))AND([Extent2]。[输入] = @ p__linq__0)&#34;

3 个答案:

答案 0 :(得分:5)

这是在实体框架中映射视图时经常发生的事情。与常规数据库表不同,视图通常没有明确唯一的键值。当EF遇到具有相同主键值的行时,它只会复制属于它已知道的键的行。在连接中,这可能导致EF生成更多子记录,因为这个第一个已知行可能比实际数据库行有更多子项。

修复方法是确保视图具有唯一标识行的字段(或字段组合)。当然,在EF中,这应该被映射为(可能是复合的)主键。

我不知道为什么EF会显示此行为。我认为应该有可能抛出一个异常,它实现了重复的实体。这个“特征”总是会引起很多混乱。

答案 1 :(得分:1)

在调试此位置时,尝试查看在IntelliTrace窗口中执行LINQ后运行的查询。然后比较你的SQL,我认为它们是不同的。如果您没有IntelliTrace,请尝试Express Profiler。只需设置SQL Server的名称,单击Trace并监视它。我希望它会有所帮助!

答案 2 :(得分:1)

这是一个很长的镜头,但这个LINQ表达式会改变什么吗?

(from uno in context.Unos
 join duo in context.Duos on uno.CommonId equals duo.CommonId
 where uno.Amount > 0 && duo.Type == 2
 select new {Uno = uno, Duo = duo}
).ToList()

我更喜欢这种形式,因为它看起来像真正的SQL请求。不知何故,LINQ中的Join语句困扰着我......