【问题标题】:Fail to convert LINQ query result to ToList无法将 LINQ 查询结果转换为 ToList
【发布时间】:2014-04-16 07:20:25
【问题描述】:
  /// <summary>
        /// Get All Countries 
        /// </summary>
        /// <returns></returns>
        public IEnumerable<CountryVM> GetAllCountry( )
        {
            using (Context context  = new Context() )
            {
                var countries = context.COUNTRY.Select(c => new CountryVM()
                     {
                         ID = c.ID,
                         DESCRIPTION = c.DESCRIPTION,
                     }

                ).ToList(); // Gets Exception here.
                return countries;
            }

为什么我无法转换为 ToList() ?

我得到以下异常:

LINQ to Entities 无法识别该方法 'System.Collections.Generic.List1[LANGUAGE] ToList[LANGUAGE](System.Collections.Generic.IEnumerable1[LANGUAGE])' 方法,并且该方法不能翻译成商店表达式。

【问题讨论】:

  • 您引用的是System.Linq 吗?
  • 是的,我指的是 System.Linq

标签: c# linq entity-framework


【解决方案1】:

一个常见的错误,因为你可能会多次遇到它,请让我解释一下为什么会发生这种情况。

让我们阅读错误信息:

LINQ to Entities 无法识别该方法

Linq to entity,将 linq 表达式转换为 SQL 的库(假设您使用的是 SQLServer 数据库)不理解您要求它执行的操作。它没有得到什么?

'System.Collections.Generic.List1[LANGUAGE] ToList[LANGUAGE] (System.Collections.Generic.IEnumerable1[LANGUAGE])' 方法

这是一个相当长且混乱的签名,因为我们不习惯看到这样的命名空间和返回类型,但它是您要求 Linq2Entities 翻译的方法: ToList(IEnumerable) 哪个返回一个列表。您可能在某处的 EntityCollection&lt;LANGUAGE&gt; 上调用了扩展方法 .ToList()。

而且这个方法不能翻译成商店表达式。

在那里,它说,它无法将您的 Linq 表达式转换为存储(读取:SQL)表达式。

为什么 Linq2Entities 试图将您的 EntityCollection&lt;LANGUAGE&gt;.ToList() 转换为 SQL ?因为 lambda 表达式(x =&gt; do some stuff 部分)中的所有内容都将转换为 SQL。由于在显示的代码中没有提到 EntityCollection,我不得不猜测它在 CountryVM 的构造函数中。

这就是 Zunair Zubair 的答案有效的原因:您的 .Select(),因此您的 lambda 表达式,不是由 Linq2Entities 翻译的,因为您是在一个对象上调用它,所以不涉及 SQL,因此没有翻译问题.

解决方案

很难提出任何建议,因为我不知道您要在构造函数中实现什么,但可能的解决方案是:

using (Context context = new Context() )
{
    List<LANGUAGE> langs = context.LANGUAGE.ToList();
    return context.COUNTRY.Select(c => new CountryVM(langs)
    {
        ID = c.ID,
        DESCRIPTION = c.DESCRIPTION,
    }).ToList();
}

并从第二个构造函数中删除假设的context.LANGUAGE.ToList();。这涉及对数据库的两个请求,并且可以进一步优化,但不能不知道您的意图和表外键。

【讨论】:

  • 我还想问你一件事,如果我使用 EF,是否有必要创建 View Model 类,因为 EF 已经生成了所有必需的 Model 类。我可以使用这些类使用 LINQ 从数据库中获取数据并显示它们吗?有人告诉我,我需要创建 View Model 类来将数据从 DAL 发送到 Controller,然后再查看。 -谢谢
  • 我不是 MVC 和 MVVM 方面的专家,但是 EF 生成的类应该只能由您的 DAL/模型访问,并且您的模型类应该提供或多或少反映这些 EF 类的类。这将允许您更轻松地自定义它们(即,您可能希望在某些时候使它们可序列化,因为如今 WebServices 无处不在)
【解决方案2】:

我怀疑这个表达式

context.COUNTRY.Select(c => new CountryVM() { ID = c.ID, DESCRIPTION = c.DESCRIPTION, })

返回单个实体而不是可枚举,这就是它无法转换为列表的原因。

【讨论】:

  • 不,它没有返回单个实体
【解决方案3】:

你可以试试下面的

var countries = context.COUNTRY.ToList().Select(c => new CountryVM()
                 {
                     ...
                 }

            ).ToList();
            return countries;

【讨论】:

  • 在ToList() 之前转换不会解决问题,并且没有任何贡献,因为Select 无论如何都会返回IEnumerable。
  • ToList()(或任何其他将执行 IQueryable 的方法)首先被调用,将用户数据带入 .NET 内存,然后执行后续的转换选项。
  • 即使它确实有效,也无法编写代码。解决症状而不是问题几乎总是不好的做法。
  • @Aron 已接受,但仍不应用作解决方案 :)
  • 这个答案虽然有效,但应该警告它的缺点,即当只需要DESCRIPTION和ID时,它会检索COUNTRY表的每一列,因此可能会降低性能。
【解决方案4】:

如果你的 c.ID 和 c.DESCRIPTION 是标量属性,这不应该工作吗..

var countries = (from c in context.COUNTRY
                 select new CountryVM()
                 {
                     ID = c.ID,
                     DESCRIPTION = c.DESCRIPTION,
                 }).ToList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-24
    • 2012-07-05
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多