2

我有几个查询类似于下面的两个示例:

// 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。Symbol(和 m. DataSeriesdataSeries)是相同的类型。

是的,我可以更改查询以使用 P/F 键关系,如下所示:

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

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

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

4

2 回答 2

2

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

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

您必须在where子句中指定数据库引擎能够理解的内容,这基本上是一个WHERE基于原始类型 ( int, bigint,...) 中的 ID 的 SQL 子句。

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

Markets.ToList().Where(m => m.DataSeries == dataSeries);

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

你真的应该where对数据库执行,这意味着你必须使用原始类型进行比较:

Markets.Where(m => m.DataSeries.ID == dataSeries.ID);
于 2013-02-06T15:38:46.710 回答
1

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

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

于 2013-02-06T14:57:15.787 回答