使用EF4如何跟踪记录是Skip()的一部分。Take()结果集

时间:2011-05-05 16:15:23

标签: c# sql linq entity-framework

因此,使用EF4,我正在运行以此常用功能结束的搜索查询:

query = query.Skip(5).Take(10);

数据库中的那些记录有一个名为ImpressionCount的列,我打算用它来计算每条记录在搜索结果页面上显示的次数。

最有效的方法是什么?在我的脑海中,我只是看一下结果集,获取一个ID列表,然后使用ADO.NET再次点击数据库来执行以下操作:

UPDATE TableName SET ImpressionCount = ImpressionCount + 1 WHERE Id IN (1,2,3,4,5,6,7,8,9,10)

看起来很简单,只是想知道是否有更多的.NET 4 / Linq-ish方法来做到这一点,我没想到。不涉及对数据库的另一次打击的那个也不错。 :)

编辑:所以我倾向于IAbstract的回答作为答案,因为它似乎没有“内置”的方式来做到这一点。我不认为有,但从来没有伤害过要求。但是,我认为我想抛出的唯一问题是:是否可以编写一个只能对此特定查询进行操作的SQL触发器?我不希望ImpressionCount更新记录的每个选择语句(例如,当有人去查看详细信息页面时,这不是印象 - 如果管理员在后端编辑记录,那不是印象) ......可能使用LINQ或没有?

SQL Server会以某种方式需要能够识别该查询是由该Linq命令生成的,不确定是否可能。这个站点预计会有相对较多的流量,所以我只是想尽可能地进行优化,但如果它太过分了,我可能会继续为每一页结果再次点击数据库一次。

2 个答案:

答案 0 :(得分:5)

在我看来,最好继续使用SQL命令运行。仅仅因为我们拥有LINQ并不意味着总是是最佳选择。您的陈述为您提供了一次性通话流程来更新展示次数,而且应该相当快。

答案 1 :(得分:1)

您可以在技术上使用.Selectmodify each element in a returned result,但这不是惯用的C#/ linq,所以最好使用foreach循环。

示例:

var query = query.ToList().Select(x => { x.ImpressionCount++; return x; });

正如IAbstract所说,小心性能问题。使用上面的示例,或foreach将执行10次更新。你的一个更新声明更好。

我知道Linq2NHibernate有同样的问题 - 试图坚持使用Linq对于更新没有任何好处(这就是为什么它被称为“语言集成查询”);

修改

实际上,可能没有理由说EF4或NHibernate无法解析select表达式,意识到它是一个更新,并将其转换为更新语句并执行它,但当然两个框架都不会这样做。如果这可能发生,您需要.Update()的新IQueryable<T>扩展方法明确声明您正在修改数据。使用.Select()是一个肮脏的黑客。

...这意味着您没有理由不能为.Update(x => x.ImpressionCount++)编写自己的IQueryable<T>扩展方法来输出您想要的SQL并调用ExecuteStoreCommand,但它将是一个很多工作。