我看到Linq与Entitites的行为不符合我对Linq如何工作的理解。请考虑下面的代码片段:使用Linq与OrderByDescending和SaveChanges的实体
MWGRCEntities entities = new MWGRCEntities();
foreach (EDMXModel.Classes.RiskScoreMetric rsm in entities.RiskScoreMetrics.Where(rsmq.StatusCode != (int)KnownCodes.RiskScoreMetricStatusInActive))
{
//Magic happens here...
rsm.ImpactOverall = (rsm.ImpactWorkingGroup + rsm.ImpactExecutive)/2;
rsm.LikelihoodOverall = (rsm.LikelihoodWorkingGroup + rsm.LikelihoodExecutive)/2;
}
int rank = 0;
double prevScore = -1;
double score = -2;
foreach (EDMXModel.Classes.RiskScoreMetric rsm in entities.RiskScoreMetrics.Where(rsmq.StatusCode != (int)KnownCodes.RiskScoreMetricStatusInActive).OrderByDescending(rsmq => Math.Round((Math.Round(rsmq.ImpactOverall, 3) + Math.Round(rsmq.LikelihoodOverall, 3)), 3)))
{
score = Math.Round((Math.Round(rsm.ImpactOverall, 3) + Math.Round(rsm.LikelihoodOverall, 3)), 3);
if (score != prevScore)
rank++;
rsm.Ranking = rank;
prevScore = score;
}
entities.SaveChanges();
我预计RiskScoreMetric对象将在使用ImpactOverall和LikelihoodOverall值在第一foreach循环设置第二个foreach循环进行排序。但是,看起来Linq正在基于原始ImpactOverall和LikelihoodOverall值(如数据库中的值而不是内存中的值)对第二个foreach循环进行排序。我可以简单地通过在第二个foreach循环之前添加第二个对entity.SaveChanges()的调用来修复代码。
任何人都可以告诉我,如果这种行为是预期的,如果是的话,为什么?
谢谢!
真棒回应。非常感谢你。我注意到有些方法不能用于这些表达式,并且不知道为什么。我现在明白了更多的事情。这是否意味着如果我将一个对象插入到上下文中,然后尝试使用select linq查询找到它,我不会找到它,因为它没有被插入到数据库中? – AEberhard 2012-08-07 21:53:23
@AEberhard:是的,确切地说。你所看到的例外可能是臭名昭着的“不能转化为商店表达”的例外,它是最常见的问题之一,意味着什么。我相信人们对此感到困惑的是“商店表达”这个术语,99%的案例都意味着“SQL”。我认为他们正在使用更抽象的术语,因为EF不需要翻译成SQL。如果有一家公司拥有一个特殊的数据库系统和一个名为“Babble”的专有查询语言,他们可以为Babble编写一个LINQ to Entities提供程序。那么“商店表达”将会是“Bab”“。 – Slauma 2012-08-07 22:07:48