一个简单的Where子句在EF5中停止工作

时间:2013-02-06 14:46:37

标签: c# entity-framework entity-framework-5 where-clause

我有几个查询看起来像下面的两个例子:

// Example 1:
var dataSeries = (from d in DataSeries
                  where d.Symbol == symbol
                  select d).FirstOrDefault();

// Example 2:
return Markets.Where(m => m.DataSeries == dataSeries).ToArray();

在我运行“从数据库更新模型...”之前,哪个工作正常。现在,我收到了一个N​​otSupportedException:

  

无法创建类型的常量值   'MyTest.Symbol'。只有原始类型或枚举   在这种情况下支持类型。

是的,我确认符号和d。符号(以及m。 DataSeries dataSeries )是相同类型的。

是的,我可以改变我的查询以使用像这样的P / F键关系:

var dataSeries = (from d in DataSeries
                  where d.Symbol.Id == symbol.Id
                  select d).FirstOrDefault();

但是当对象关系工作正常时,我真的不想将我的所有代码都改为P / F键关系。

问题:如何让我的第一个例子再次运作?

2 个答案:

答案 0 :(得分:2)

您无法在针对数据库执行的LINQ查询中编写类似的where子句。请记住,代码将被转换为SQL ,并将在数据库引擎上运行。

因此,对于您的第一个示例,Entity Framework如何知道如何比较复杂类型MyTest.Symbol的两个实例? EF根本不能,因为这种比较没有合适的SQL。

您必须在where子句中指定数据库引擎将理解的内容,这基本上是基于基本类型中的ID的WHERE子句int,{ {1}},...)。

可以使用bigint从数据库中获取所有数据,并在内存结果列表中应用.ToList()子句,因此where子句不必转换为SQL:

where

但是你将失去数据库服务器的所有好处:大量使用内存(一切都在上下文中加载),性能不佳等等。

你真的应该对数据库执行Markets.ToList().Where(m => m.DataSeries == dataSeries); ,这意味着你必须使用原始类型进行比较:

where

答案 1 :(得分:1)

您的示例不起作用,因为EF不支持LINQ查询中的对象比较,它不知道如何将其转换为SQL语句。

即使使用DataSeries.ToList()首先将所有DataSeries提取到内存中,除非符号属于加载列表或者您必须覆盖,否则比较d.Symbol ==符号仍然不起作用等于方法。这是因为默认情况下,只有2个对象引用同一个实例时才相等。