LINQ和SQL中看似等效的查询返回不同的结果
本文关键字:查询 返回 结果 SQL LINQ | 更新日期: 2023-09-27 18:20:55
不确定为什么它被链接为重复。问题大不相同。答案不同。不知道该改变什么。如果有人看到我缺少的东西,请告诉我
我使用这两个查询得到了不同数量的结果。在分析了几个小时后,我需要认输,承认我无法发现显著性的差异。由于我的方法库被清空了,我请求帮助。
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
第一个问题是,以上两种说法是否确实相等,或者我是否遗漏了什么。第二个问题是我遗漏了什么(如果有的话),或者如何解决(如果没有的话)。
- 对同一数据库进行调用
- 结果的数量相差甚远(142和1437)
- 为内部联接提取相同的结果集
- Uno和Duo都是视图,而不是表
我还能验证什么?
编辑
经过社区的大力支持,我们确定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管理器中执行那个字符串会产生142个结果(就像上面例子中的查询,SQL版本),它与它的区别很小。然而,执行LINQ查询本身会产生1437个结果。我太困惑了,甚至都哭不出来。。。
"SELECT ''r''n[Extent1]。[CommonId]AS[CommonId],''r''n[Extent1]。[X] AS[X]''r''n FROM(SELECT[Uno].[CommonId]AS[CommonId],''n[Uno].X]AS[X]''n FROM[Finance].[Uno]AS[Uno])AS[Extent1]''r''n INNER JOIN].[V]AS[V]''n FROM[Finance].[Duo]AS[Duo])AS[Extent2]ON[Extent1]。[CommonId]=[Extent2]。[CommonId]''r''n WHERE([Extent1].[X]>强制转换(0为十进制(18))AND([Extend2].[Type]=@p_linq__0)"
这是在实体框架中映射视图时经常发生的事情。与常规数据库表不同,视图通常没有明确的唯一键值。当EF遇到主键值相同的行时,它只是复制属于它已经知道的键的行。在联接中,这可能导致EF生成更多的子记录,因为第一个已知行可能比实际数据库行具有更多的子行。
修复方法是确保视图具有唯一标识行的字段(或字段组合)。当然,在EF中,这应该被映射为(可能是复合的)主键。
我不知道EF为什么会表现出这种行为。我认为它应该有可能抛出一个异常,即它具体化了重复的实体。这个"特性"总是引起很多混乱。
这是一个很长的机会,但这个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语句让我很困扰…
调试此位置时,请尝试查看在IntelliTrace窗口中执行LINQ后运行的查询。然后与您的SQL相比,我认为它们是不同的。如果您没有IntelliTrace,请尝试Express Profiler。只需设置SQL Server的名称,单击"跟踪"并监视它。希望它能有所帮助!