2010-04-08 139 views
6

我想弄清楚为什么LINQ中的简单查询返回奇数结果。LINQ查询返回多个副本的第一个结果

我有一个在数据库中定义的视图。它基本上汇集了其他几张表并进行一些数据传输。除了处理大型数据集并且可能有点慢之外,它确实没有什么特别之处。

我想查询这个基于long的视图。下面的两个示例查询显示对此视图的不同查询。

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(); 

第一个应该退回列表。第二个将是一个匿名对象的列表。

当我在实体框架这些查询第一个将手我回到结果,其中他们都是一模一样的列表。

第二个查询将手我回数据,其中的帐号是我查询和其他值不同的一个。这似乎是在每个帐号的基础上做到这一点,即如果我要查询一个帐号或另一个帐号的所有位置对象将具有相同的值(该帐户的位置列表中的第一个)和第二个账户将拥有一组所有具有相同值的Position对象(同样,它是Position对象列表中的第一个)。

我可以写SQL是实际上是相同的或者两个EF查询。他们都回来了结果(如四),显示正确的数据,一个帐号与不同的证券号码。

这是为什么发生?有没有什么我可以做错的,这样如果我有第一个查询的四个结果上面的第一个记录的数据也出现在2-4的对象?

我不明白会造成这种情况/可能会造成这种情况。我向Google搜索了各种关键字,并没有看到有人遇到过这个问题。我们部分分类了位置类以增加功能(智能对象)和一些智能属性。甚至有一些构造函数提供了一些视图模型类型支持。这些都不是在请求中调用的(我对此99%肯定)。不过,我们在整个应用中都采用了相同的模式。

我能想到的唯一的事情是,在EDMX的映射是扭曲。如果EDMX中的“主键”在构造视图的方式上并不是唯一的,那么是否有这种方式会发生?我在想,将这个模型导入EDMX的开发者会让设计师自动选择独特的东西。

任何帮助会给haggered dev一些希望!

+3

抓住生成的SQL脚本并在Management Studio中以交互方式运行它,以查看实际正在发生的事情 – 2010-04-08 19:20:40

+0

如上所述,也许使用分析器查看正在执行的SQL。 – 2010-04-08 19:52:19

回答

13

这个问题的答案特定问题是这样的:

确保你的实体按键是独一无二的! !

在EDMX中生成的视图有三个列/属性被标记为实体键(我猜是组合为记录创建一个唯一的ID)。

在我的查询中,这三列完全一样。我假定实体框架吓了一跳,并将第一条记录放入所有后续记录中,直到其中一列发生更改(因此创建了一个新的唯一“集合”)。

现在我已经想通了,我回头看看这个信息第一次被使用的地方,并看到一个分组语句被首先应用(数据正在通过应用程序中另一个地方的存储过程被查询)。该小组展示了其中一个实体关键字栏,使其始终是唯一的。这会导致该位置的结果显示正常。

我的解决方案是添加一个新的列到这个视图,只是投射一个GUID(在SQL中使用NEWID())。问题是我知道不知道如何告诉EDMX使用这个新添加的属性作为映射视图的唯一实体键!

-I'm关闭此为固定的,因为我知道什么问题,并会问一个新的问题我的另一个问题。感谢那些花时间回答的人的所有见解!

+1

你介意链接到另一个问题吗? – defines 2011-10-26 20:10:29

+0

plz让我们知道你是如何设置作为一个PK在视图或编辑 – 2018-02-10 07:34:41

+0

嘿家伙,我希望我仍然有权访问此代码库。在我发布这个问题后,我离开了这个职位。这已经有一段时间了,因为我不得不在EF中这样做。在流利的API中这将是微不足道的。如果我可以正确回忆,我删除了所有单个的键,以便在映射中不使用组合键,而是使用在视图中创建的GUID作为PK。 – 2018-02-12 16:41:11

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>