如何简化 Entity Framework 条件下的内存对象相等性比较?
How to streamline memory object equality comparison in Entity Framework condition?
如果我通过 Entity Framework 加载一个对象并保留它以便以后使用它 - 例如在相等过滤器中 - Entity Framework 会抛出以下错误:
Unable to create a constant value of type 'MyType'. Only primitive types or enumeration types are supported in this context.
这可以通过在 MyType
上使用识别性 value/value 组合轻松解决,例如 .Where(x => x.Name == MyTypeMemoryInstance.Name)
.
但是,我想知道是否有一种替代方法可以在不提供原始类型的情况下允许进行相等比较,所以我可以 .Where(x => x == MyTypeMemoryInstance)
代替,并且仍然在 SQL 中这样做,而不是在记忆中。
从概念上讲,如果我可以提供 LINQ 到 SQL 的转换以及用于给定类型的特定原始类型比较,这可以解决,类似于覆盖 C# 中的常规相等性比较,但我不知道这是否真的可能。谢谢。
问题是 Linq to Entities 查询被转换为 SQL。 Linq 提供程序无法转换两个对象实例以在 sql 中进行比较。这就是它抛出该异常的原因,因为它需要像在 SQL.
中那样使用原始类型
一种解决方案可以使用 AsEnumerable
扩展方法,从 Linq to Entities 切换到 Linq to Objects。如果你这样做:
var query=context.YourDbSet.AsEnumerable().Where(x => x== MyTypeMemoryInstance)....
但请谨慎使用此解决方案。您将把 table 中的所有行加载到内存中。另一个部分解决方案可能是,如果您有多个条件,那么您可以先应用一些过滤器,然后在确实需要时应用实例比较:
var query=context.YourDbSet.Where(...).AsEnumerable().Where(x => x== MyTypeMemoryInstance)....
我能想到的最好的,因为在 where 子句中你有 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();
如果我通过 Entity Framework 加载一个对象并保留它以便以后使用它 - 例如在相等过滤器中 - Entity Framework 会抛出以下错误:
Unable to create a constant value of type 'MyType'. Only primitive types or enumeration types are supported in this context.
这可以通过在 MyType
上使用识别性 value/value 组合轻松解决,例如 .Where(x => x.Name == MyTypeMemoryInstance.Name)
.
但是,我想知道是否有一种替代方法可以在不提供原始类型的情况下允许进行相等比较,所以我可以 .Where(x => x == MyTypeMemoryInstance)
代替,并且仍然在 SQL 中这样做,而不是在记忆中。
从概念上讲,如果我可以提供 LINQ 到 SQL 的转换以及用于给定类型的特定原始类型比较,这可以解决,类似于覆盖 C# 中的常规相等性比较,但我不知道这是否真的可能。谢谢。
问题是 Linq to Entities 查询被转换为 SQL。 Linq 提供程序无法转换两个对象实例以在 sql 中进行比较。这就是它抛出该异常的原因,因为它需要像在 SQL.
中那样使用原始类型一种解决方案可以使用 AsEnumerable
扩展方法,从 Linq to Entities 切换到 Linq to Objects。如果你这样做:
var query=context.YourDbSet.AsEnumerable().Where(x => x== MyTypeMemoryInstance)....
但请谨慎使用此解决方案。您将把 table 中的所有行加载到内存中。另一个部分解决方案可能是,如果您有多个条件,那么您可以先应用一些过滤器,然后在确实需要时应用实例比较:
var query=context.YourDbSet.Where(...).AsEnumerable().Where(x => x== MyTypeMemoryInstance)....
我能想到的最好的,因为在 where 子句中你有 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();