使用包含使用 EF 查询记录时出现多个运行时错误

本文关键字:运行时错误 记录 包含使 EF 查询 | 更新日期: 2023-09-27 18:32:44

我正在使用 EF-5 编写更新方法,但在选择记录以进行目标更新时遇到问题。

public void Update(List<MyEntities> entitiesToUpdate)
{
    // Get rows that match IDs
    var findUpdateRows = this
        ._context
        .MyEntity
        .Where(w => entitiesToUpdate
            .Select(s => s.SomePropertyId)
            .ToList()
            .Contains(w.SomePropertyId)
        )
        .ToList();
}
    // run time error - LINQ to Entities does not recognize the method 'System.Collections.Generic.List`1[System.Int32] ToList[Int32](System.Collections.Generic.IEnumerable`1[System.Int32])' method, and this method cannot be translated into a store expression.

如果我改为尝试:

    // Get rows that match IDs
    var findUpdateRows = this
        ._context
        .MyEntity
        .Where(w => entitiesToUpdate
            .Select(s => s.SomePropertyId)
            .Contains(w.SomePropertyId)
        )
        .ToList();
    // Run time error - Unable to create a constant value of type 'xxx.MyEntities'. Only primitive types or enumeration types are supported in this context.

在使用以下方法时,我可以让该方法按预期工作(但我想了解并了解如何在没有单独的 idsToUpdate var 和赋值的情况下完成相同的工作):

    // Create list of IDs to update
    List<int> idsToUpdate = new List<int>();
    entitiesToUpdate.ForEach(fe => idsToUpdate.Add(fe.SomePropertyId));
    // Get rows that match IDs
    var findUpdateRows = this
        ._context
        .MyEntity
        .Where(w => idsToUpdate.Contains(w.SomePropertyId))
        .ToList();

使用包含使用 EF 查询记录时出现多个运行时错误

此异常

无法创建类型的常量值...

始终指示在 LINQ 语句中的某个位置使用对象(类实例),其中 EF 只能处理基元值。所以第一步是看:我在哪里使用对象?

var findUpdateRows = this._context.MyEntity // here
                         .Where(w => entitiesToUpdate // here
                                     .Select(s => s.SomePropertyId)
                                     .Contains(w.SomePropertyId))

现在我们知道只有this._context.MyEntity的行会运行,所以它应该是entitiesToUpdate .你直觉地想通了。

原因是整个表达式(entitiesToUpdate是一个Expression)被翻译成 SQL,而 EF 根本没有办法将List(类)对象转换为 SQL(只是试着想象它在 SQL 中应该是什么样子:/)。

所以你做了正确的事情,虽然

var idsToUpdate = entitiesToUpdate.Select(s => s.SomePropertyId).ToList();

有点短。