C# 使用EF4如何跟踪记录作为Skip().Take()结果集一部分的次数
因此,我使用EF4运行一个搜索查询,该查询以以下常见函数结尾:C# 使用EF4如何跟踪记录作为Skip().Take()结果集一部分的次数,c#,sql,linq,entity-framework,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 (
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)
看起来很简单,只是想知道是否有一种更像.NET4/Linq的方式来实现这一点,我没有想到。一个不涉及对数据库的另一次点击的也很好。:)
编辑:因此我倾向于使用IAbstract的回答作为答案,因为似乎没有“内置”的方法来实现这一点。我不认为有,但问也无妨。然而,我想我要提出的另一个问题是:是否有可能编写一个只能对这个特定查询进行操作的SQL触发器?我不希望ImpressionCount在记录的每个select语句上都进行更新(例如,当有人去查看详细信息页面时,这不是一个印象——如果管理员在后端编辑记录,那就不是一个印象)…是否可以使用LINQ或no
SQL Server可能需要能够识别查询是由该Linq命令生成的,但不确定这是否可行。这个网站的访问量相对较大,所以我只是尽可能地进行优化,但如果过度,我可能会继续进行,并针对每个结果页面再次访问数据库一次。从技术上讲,您可以使用
。选择to,但这不是惯用的C#/linq,因此,最好使用foreach
循环
例如:
var query = query.ToList().Select(x => { x.ImpressionCount++; return x; });
正如IAbstract所说,要小心性能问题。使用上面的示例,或一个foreach
将执行10次更新。你的一个更新语句更好
我知道Linq2NHibernate也有同样的问题——试图坚持使用Linq对更新没有任何好处(这就是为什么它被称为“语言集成查询”
编辑:
实际上,EF4或NHibernate可能没有理由不能解析select表达式,认识到它是一个更新,并将其转换为update语句并执行它,但肯定两个框架都不会这样做。如果这是可能发生的事情,您可能需要一个新的.Update()
扩展方法,用于IQueryable
,以明确声明您正在修改数据。使用.Select()
,因为这是一种肮脏的黑客行为
。。。这意味着您没有理由不能为IQueryable
编写自己的.Update(x=>x.ImpressionCount++)
扩展方法,以输出您想要并调用的SQL,但这将需要大量的工作。在我看来,最好继续使用SQL命令运行。我们拥有LINQ并不意味着它总是最好的选择。您的声明为您提供了一个一次调用的过程来更新印象计数,应该相当快。最终结果是一个副作用——“非棘手”的方法是对每个结果依次更新,这不符合其他要求。我会刺伤某人,因为他使用Select引入了副作用。此外,它也不会减少SQL语句的数量。@pst-我同意,但我使用的是Jon Skeet方法,“不要这样做,但如果忽略我的警告,你会怎么做。”+1我同意,使用原始SQL并不意味着你违反了法律,但我们应该使用最适合这种情况的方法。