订单实体框架通过rowversion属性查询,在存储和内存中 [英] Order Entity Framework query by rowversion property, in store and in memory

查看:229
本文介绍了订单实体框架通过rowversion属性查询,在存储和内存中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我的(Code First)实体框架模型中有一个实体,如下所示:

  public class Foo 
{
[Key]
[MaxLength(50)]
public string FooId {get;组;

[Timestamp]
[ConcurrencyCheck]
public byte [] Version {get;组; }
}

进一步假设我需要获取最近几个这些项目。我可以用一个相当简单的LINQ表达式来实现,它被转换成正确的SQL,并且运行正常。

  var recentFoos = db.Foos.OrderBy(f => f.Version).Take(10); 

现在,如果这个查询发生在我想要测试的方法中,事情会变得更加复杂。我有一个假的上下文和实体集合的设置,一切都正常。但是,因为 byte [] 不能直接排序,尝试执行该代码会抛出一个 ArgumentException (At至少一个对象必须实现IComparable。)。



另一方面,如果我使用 OrderBy()它采用比较器,这将在内存中运行,但会抛出异常(...此方法无法转换为存储表达式)尝试针对数据库运行。



有没有办法a)编写一个可以在两种情况下正确运行的LINQ查询,或者b)可靠地检测哪种情况,以便我的代码可以使用正确的重载进行排序? / strong>

解决方案

我最终实施了解决方案 jnm2建议:写一个 ExpressionVisitor 重写查询从正常查询使用的谓词唯一重载到内存查询所必需的重载。我不得不修改原始Microsoft示例代码为假的 DbSet 允许这些访问者在正确的时刻插入并使用。



一个Gist与我的代码可以在这里找到。如果有人可以提出更优雅的方式来申请访问者,我绝对愿意提供建议。


Assume I have an entity in my (Code First) Entity Framework model that looks like this:

public class Foo
{
  [Key]
  [MaxLength(50)]
  public string FooId { get; set; }

  [Timestamp]
  [ConcurrencyCheck]
  public byte[] Version { get; set; }
}

Assume further that I need to fetch the most recent few of these items. I can do that with a fairly simple LINQ expression, which gets translated into the correct SQL, and runs fine.

var recentFoos = db.Foos.OrderBy(f => f.Version).Take(10);

Now, if that query happens in a method that I also want to test, things get more complicated. I have a setup with fake context and entity collections, and that all works fine. But, because byte[] can't be sorted directly, trying to execute that code throws an ArgumentException ("At least one object must implement IComparable.").

On the other hand, if I use the overload of OrderBy() that take a comparer, that will run in memory, but throw an exception ("…this method cannot be translated into a store expression.") trying to run against the database.

Is there a way to either a) write a single LINQ query that will run correctly in both circumstances, or b) to reliably detect which case pertains, so that my code can sort using the correct overload?

解决方案

I ended up implementing the solution jnm2 suggested: writing an ExpressionVisitor to rewrite the query from the predicate-only overload used by normal queries to the overload necessary for in-memory querying. I had to rework the original Microsoft sample code for fake DbSet to allow these visitors to be plugged in and used at the right moment.

A Gist with my code can be found here. If anyone can suggest a more elegant way to apply the visitors, I'm definitely open to suggestions.

这篇关于订单实体框架通过rowversion属性查询,在存储和内存中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆