我正在试图弄清楚为什么LINQ中的简单查询会返回奇怪的结果。
我在数据库中定义了一个视图。它基本上汇集了其他几个表,并做了一些数据调整。除了它处理大型数据集并且可能有点慢之外,它确实没什么特别的。
我想基于很长时间查询此视图。下面的两个示例查询显示了对此视图的不同查询。
var la = Runtime.OmsEntityContext.Positions.Where(p => p.AccountNumber == 12345678).ToList();
var deDa = Runtime.OmsEntityContext.Positions.Where(p => p.AccountNumber == 12345678).Select(p => new { p.AccountNumber, p.SecurityNumber, p.CUSIP }).ToList();
第一个应该交回一个List。第二个是匿名对象列表。
当我在实体框架中执行这些查询时,第一个查询将把结果列表交给我,它们都完全相同。
第二个查询将返回数据,其中帐号是我查询的号码,其他值不同。这似乎是基于每个帐号来执行此操作,即如果我要查询一个帐号或另一个帐户的所有位置对象将具有相同的值(该帐户的位置列表中的第一个)和第二个帐户将有一组所有具有相同值的Position对象(同样,它是Position对象列表中的第一个)。
我可以编写实际上与两个EF查询中的任何一个相同的SQL。他们都返回显示正确数据的结果(比如四个),一个账号与不同的证券号码。
为什么会这样?是否存在我可能做错的事情,以便如果我在上面的第一个查询中有四个结果,那么第一个记录的数据也会出现在第2-4个对象中???
我无法理解会导致这种情况的原因。我在谷歌搜索了各种关键字,但没有看到任何人遇到过这个问题。我们将Positions类分类为添加功能(智能对象)和一些智能属性。甚至有一些构造函数提供了一些视图模型类型支持。在请求中没有调用它(我对此肯定是99%)。但是,我们在整个应用程序中执行相同的模式。
我唯一能想到的是EDMX中的映射很棘手。有没有一种方法,如果EDMX中的“主键”在构造视图的方式中实际上不是唯一的,会发生这种情况?我认为将这个模型导入EDMX的开发者可以让设计师自动选择独一无二的东西。
任何帮助都会给一个憎恨的开发者一些希望!
答案 0 :(得分:13)
这个特定问题的答案是:
确认你的实体钥匙是独一无二的!
在EDMX中生成的视图有三个列/属性被标记为实体键(我想这是记录的唯一ID的组合)。
在我的查询中,这三列完全相同。我假设实体框架吓坏了,只是将第一条记录放入所有后续记录中,直到其中一列更改为止(因此是一个新的唯一“集合”)。
现在我已经想到了,我回头看了第一次使用此信息的地方,并看到首先应用了一个分组语句(数据是通过应用程序中另一个地方的存储过程查询的) 。该组扁平化了一个实体键列,使其始终是唯一的。这会导致该位置的结果显示正常。
我的解决方案是在此视图中添加一个新列,该列仅投影GUID(在SQL中使用NEWID())。问题是我知道不知道如何告诉EDMX使用这个新添加的属性作为映射视图的唯一实体键!
- 我正在关闭这个,因为我知道问题是什么,并将在一个新问题中提出我的另一个问题。感谢那些花时间回答的人的所有见解!
答案 1 :(得分:0)
您是否尝试过这种语法?无法想象这是原因,但谁知道......
using (var dc = new OmsEntityContext())
{
var la = (from p in dc.Position
where p.AccountNumber = "12345678"
select p).ToList();
}
和
using (var dc = new OmsEntityContext())
{
var deDa = (from p in dc.Position
where p.AccountNumber = "12345678"
select new {p.AccountNumber, p.SecurityNumber, p.CUSIP}).ToList();
}
</longShot>