如何在实体框架条件下简化内存对象平等比较



如果我通过实体框架加载对象,并坚持以后使用它 - 例如,在平等过滤器中 - 实体框架会引发以下错误:

无法创建" mytype"类型的恒定值。在这种情况下仅支持原始类型或枚举类型。

然后,可以通过使用MyType上的识别值/值组合来轻松解决此问题,例如.Where(x => x.Name == MyTypeMemoryInstance.Name)

但是,我想知道是否有替代方案可以允许相等性比较而无需提供原始类型,因此我可以改用.Where(x => x == MyTypeMemoryInstance),并且仍然在SQL而不是在内存中进行。

从概念上讲,如果我可以提供特定的原始类型与给定类型使用的特定原始类型的比较,则可以解决这可以解决,类似于C#中的常规平等比较,但我不知道这是否实际上是可能的。谢谢。

我能想到的最好,因为在该子句中,您的func是:

public class MyType
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Func<MyType, bool> GetQuery()
    {
        // or whatever equals you would like
        return x => x.Name == this.Name && x.Id == this.Id;
    }
}

然后使用它,例如:

var first = ctx.MyTypes.First();
var listContainingLoadedThings = ctx.MyTypes.Where(first.GetQuery()).ToList();

问题是将LINQ到实体查询转换为SQL。LINQ提供商无法将两个对象实例转换为在SQL中进行比较。这就是为什么它会引发异常,因为它需要像在SQL中一样使用原始类型。

一种解决方案可以使用AsEnumerable扩展方法,以从Linq到实体再到Linq到对象。如果您做类似:

的事情
var query=context.YourDbSet.AsEnumerable().Where(x => x== MyTypeMemoryInstance)....

但是要小心这种解决方案。您将从该表加载所有行。另一部分解决方案可能是如果您有多个条件,则可以先应用一些过滤器,然后以后应用实例比较,如果您确实需要这样做:

var query=context.YourDbSet.Where(...).AsEnumerable().Where(x => x== MyTypeMemoryInstance)....

最新更新