我在实体框架4.0中比较对象时遇到了麻烦。谷歌搜索了一段时间后,我在2008年发现了一篇博文,其中说明了我的问题是什么以及它为什么会发生。Blog post describing my problem in depth。
总结博客文章,你根本无法与EF框架进行自定义对象比较。例如
public Foo
{
public int ID{get;set;}
public string Name {get;set;}
//I overrode the .Equals AND the == operator
}
public getFoo(Foo target)
{
DC.foos.FirstOrDefault(x => x == target);
}
System.NotSupportedException:无法创建类型为'Foo'的常量值在此上下文中仅支持基本类型(例如Int32,String和Guid')。
根据MicroSoft的说法,这是by design。
如果我做了一些神奇的界面或神奇的过载,有人能指点我找到是否支持这种对象比较吗? 非常感谢你!< / p>
答案 0 :(得分:6)
由于EF需要将LINQ语句转换为SQL语句,因此无法执行此操作。如果在重写的Equals()
方法中有复杂的比较逻辑,则必须在LINQ语句中复制它。
由于LINQ使用延迟执行,您可以将该逻辑封装在一个方法中,该方法返回一个可以合并到其他地方的IQueryable<T>
。
以下是一个例子:
public IQueryable<Foo> FoosEqualTo(IQueryable<Foo> allFoos, Foo target) {
return from foo in allFoos
where foo.Id == target.Id // or other comparison logic...
select foo;
}
public Foo getFoo(Foo target) {
return FoosEqualTo(DC.foos, target).FirstOrDefault();
}
答案 1 :(得分:1)
我认为你可以使用LinqKit的PredicateBuilder和反射做到这一点。或者,您可以使用反射来生成Where
Expressions
链,以执行相同的操作。
我没有时间组织一个例子,但我很确定你可以这样做。