【发布时间】:2011-10-17 06:05:21
【问题描述】:
我有一个使用实体框架模型的 MVC3 项目,我在其中标记了这样的类:
public partial class Product
{
public bool IsShipped
{
get { /* do stuff */ }
}
}
我想在 LINQ 表达式中使用它:
db.Products.Where(x => x.IsShipped).Select(...);
但是,我收到以下错误:
System.NotSupportedException 未被用户代码处理 Message=The LINQ to Entities 不支持指定类型成员“IsShipped”。 只有初始化器、实体成员和实体导航属性 支持。 Source=System.Data.Entity
我在谷歌上搜索过,但没有找到任何关于我尝试过的关于这种用法的确切信息:
public partial class Product
{
public bool IsShipped()
{
/* do stuff */
}
}
db.Products.Where(x => x.IsShipped()).Select(...);
然后我得到:
System.NotSupportedException 未被用户代码 Message=LINQ 处理 to Entities 无法识别方法 'Boolean IsShipped()' 方法, 而且这个方法不能翻译成商店表达式。
Source=System.Data.Entity
那里有一些我不想内置到 LINQ 查询本身的功能......有什么好的方法来处理这个问题?
* 更新 *
Darin 提出了有效的观点,即在 IsShipped 的实现中所做的任何事情都需要转换为 SQL 查询,而编译器可能不知道如何去做,因此将所有对象检索到内存中似乎是唯一的方法选择(除非直接查询数据库)。我试过这样:
IEnumerable<Product> xp = db.Quizes
.ToList()
.Where(x => !x.IsShipped)
.Select(x => x.Component.Product);
但它会产生这个错误:
发生关系多重性约束违规:一个 EntityReference 只能有一个相关对象,但 查询返回多个相关对象。这是不可恢复的 错误。
虽然奇怪的是这行得通:
IEnumerable<Product> xp = db.Quizes
.ToList()
.Where(x => x.Skill.Id == 3)
.Select(x => x.Component.Product);
为什么会这样?
* 更新二 *
抱歉,最后一条语句也不起作用...
* 更新 III *
我将结束这个问题,支持按照此处的建议寻求解决方案,以将我的逻辑扁平化为查询 - 讨论将移至 this new post。第二种选择,将整个原始查询检索到内存中,可能是不可接受的,但第三种将逻辑实现为对数据库的直接查询仍有待探索。
感谢大家的宝贵意见。
【问题讨论】:
-
“处理这个问题的好方法”完全取决于“做事”到底是什么。问题是是否有可以翻译成 SQL 的东西。如果“做事”是:
return MyMappedProp1 && MyMappedProp2,那么就有希望(不是你现在做的方式,而是另一种“干”的方式)。如果您在“do stuff”中打开磁盘上的文件并从中读取一个值,那么可能没有希望。所有通用解决方案都将强制您使用 LINQ to Objects 进行查询,即在过滤之前将所有内容加载到内存中。 -
@Slauma 不,我不会做任何事情,只是在“东西”中进行数据库查询......但是,请参阅我最近对这篇文章的更新
-
你在“更新”中的例外:当你只使用
IEnumerable<Product> xp = db.Quizes.ToList();时你也会得到这个吗?我相信这个问题与您的IsShipped属性无关。模型中还有其他问题。 -
@Slauma,这与达林首先获取所有内容的想法有关。我在测试中使用了
IEnumerable,但我真正想要的是一个列表,因此请考虑List<Product> p1 = db.Quizes.Select(x => x.Component.Product).ToList();工作正常,但List<Product> p1 = db.Quizes.ToList().Select(x => x.Component.Product).ToList();会产生该异常。我需要最后的.ToList(),因为我要分配给一个列表...
标签: c# .net asp.net-mvc linq entity-framework