我有几个查询看起来像下面的两个例子:
// 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();
在我运行“从数据库更新模型...”之前,哪个工作正常。现在,我收到了一个NotSupportedException:
无法创建类型的常量值 '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键关系。
问题:如何让我的第一个例子再次运作?
答案 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个对象引用同一个实例时才相等。