0

我的问题是我无法让Where语句与 Entity Framework 一起正常工作。

我有一个类,它具有定义数据库中的一行的属性intlong让我们称这些属性Id为 &Parent

public class Update
{
    public long Id { get; set; }
    public int Parent { get; set; }
}

然后我有这些更新的列表,我希望每个数据库行都应该匹配列表中的那些更新(两个属性)。

我尝试过的是,我将这些更新转换为匿名类型,并尝试仅查找那些具有完美匹配的行:int 和 long 都是相同的。

// anon type
var mapping = updates.Select(o => new { id = o.Id, parent = o.Parent}).ToList();
var results = from fa in Uvw_MyTable 
              // PROBLEMATIC WHERE
              where mapping.Contains(new { id = fa.Id, parent = fa.Parent })
              select new { fa };

但不幸的是,我总是收到一个错误:无法创建“匿名类型”类型的常量值。此上下文仅支持原始类型(“例如 Int32、String 和 Guid”)。

我也试过这样使用Any

where mapping.Any(a => fa.Id == a.id && fa.Parent == a.parent)

但我得到同样的错误。当我使用对象列表时也会发生同样的事情Update无法创建“xxx.Update”类型的常量值。此上下文仅支持原始类型(“例如 Int32、String 和 Guid”)。

任何想法如何解决这个问题?

更新

这个完全相同的查询在 LINQPad 4 中运行良好

更新 2

问题与这个问题有关吗?

更新 3

正如 Maarten 指出的那样,这个问题需要使用不同方法来重新产生相同结果的解决方案。

4

3 回答 3

1

我不确定我是否正确理解了您的代码/问题,但在我看来,这样的事情应该有效:

var results = from fa in Uvw_MyTable 
                    where updates.Any(u => u.Id fa.Id && u.Parent = fa.Parent)
                    select fa; 

我不清楚您希望使用的行为OtherTable是什么,但是上面 linq 表达式的一般形式比您使用的要有效得多。

关键是您不需要创建匿名类型来比较多个字段;因此第一个 select (into mapping) 是多余的。

于 2012-08-08T10:20:42.347 回答
1

您实际上是在代码中执行两个查询。

第一个查询是:

var mapping = updates.Select(o => new { id = o.Id, parent = o.Parent}).ToList();

第二个查询是(好的,查询没有迭代,所以从技术上讲,查询还没有在这里执行 - 挑剔):

var results = from fa in Uvw_MyTable 
              where mapping.Contains(new { id = fa.Id, parent = fa.Parent })
              select new { fa };

由于您使用的是 ToList() 方法,因此第一个查询是在您的单个语句中定义和执行的。由于现在这是一个对象列表,而不是 IQueryable,EF 无法将其转换为 SQL。您必须将其保留为 IQueryable。如果将其更改为以下内容,它应该可以工作。

var mapping = updates
    .Select(o => new { id = o.Id, parent = o.Parent}); // NOT ToList() !!
var results = from fa in Uvw_MyTable 
              where mapping.Contains(new { id = fa.Id, parent = fa.Parent })
              select new { fa };

为了解释 EF 给出的错误 - EF 只能将 IQueryable 转换为 SQL,或将原始类型(整数、字符串等)转换为参数。EF 无法将对象转换为 SQL,因为它无法以有意义的方式将对象的值传输到数据库。


更新:

The first query (I see now) is not a query at all, it's source is a variable called updates. If this is a list of objects in-memory, than this query cannot be translated as such, and you have to redesign you query (for example, loading Uvw_MyTable is memory). If 'updates' is an IQueryable (from the same context), than my answer given above should work.

于 2012-08-08T11:10:09.937 回答
0

在实体框架或 Linq to sql 中,linq 查询最终会被翻译成 sql 查询。当您使用不可转换为 sql 的类型或类时,您的 linq 查询无法转换为 sql 查询。

于 2012-08-08T10:58:51.067 回答