【问题标题】:LINQ - "Unable to create constant value of type [type]"?LINQ - “无法创建类型 [type] 的常量值”?
【发布时间】:2013-06-08 20:35:44
【问题描述】:

这是我的错误

无法创建“Courses.Model.Track”类型的常量值。此上下文仅支持原始类型或枚举类型。

这是导致它的代码:

model.Courses = db.Courses
    .Where(c => model.Tracks.Any(t => t.Certification.ID == certificate))
    .ToList();

另外,model.CoursesIEnumerable<Courses>,我不确定这是否与我的问题有关。

有人可以帮我解释一下吗?非常感谢。

【问题讨论】:

  • 什么是model.Tracks
  • 您正在选择 db.Courses 的每个值:您没有对 .Where(c => ... 子句中的 c 做任何事情。 certificate 应该是 c.certificate 吗?

标签: c# asp.net-mvc linq collections


【解决方案1】:

db.Courses 是一个IQueryable。虽然语法实际上与 IEnumerable 的 LINQ 方法相同,但在底层它们完全不同。

IQueryable 代码实际上并没有在任何地方执行。它只是创建了一堆Expression 对象,不同的查询提供者可以使用它们来做......他们想要的任何事情(在这种情况下查询数据库)。这些查询提供程序需要专门有代码来处理任何给定类型的输入。有些事情他们要么无法合理地转换为 SQL 查询,要么程序员根本没有想到或选择处理(即使它可能有合理的 SQL 翻译)。

在排序中,查询提供者只是不知道如何将model.Tracks.Any(t => t.Certification.ID == certificate) 转换为 SQL。

您只需要知道您正在使用的查询提供程序支持和不支持哪些类型的代码,并尝试将您拥有的代码操作为它可以处理的内容。这样的事情应该可以工作:

var certificates = model.Tracks.Select(t => t.Certification.ID).ToList();

model.Courses = db.Courses
    .Where(c => certificates.Contains(c))
    .ToList();

如果这是在 LINQ to objects 中执行所有这些操作的 C# 代码,那么这两个查询将是相同的,但对于查询提供程序来说它们不是。他们只是特别支持知道何时看到List.Contains 以将其映射到SQL IN 子句。他们没有为您在第一个查询中所做的添加特定支持。

【讨论】:

    【解决方案2】:

    尝试使用 LINQ 'Where In',这应该可以解决您的问题:

    var names = new string[] { "Alex", "Colin", "Danny", "Diego" };
    
    var matches = from person in people
            where names.Contains(person.Firstname)
            select person;
    

    var matches = from person in people
            where person.Firstname == "Alex" ||
                  person.Firstname == "Colin" || 
                  person.Firstname == "Danny" ||
                  person.Firstname == "Diego"
            select person;
    

    http://blogs.msdn.com/b/alexj/archive/2009/03/26/tip-8-writing-where-in-style-queries-using-linq-to-entities.aspx

    【讨论】:

      【解决方案3】:

      对于这个几乎没有必要的问题,我深表歉意,尽管 @klugerama 确实帮助我解决了这个问题。

      这有问题:

      model.Courses = db.Courses
          .Where(c => model.Tracks.Any(t => t.Certification.ID == certificate))
          .ToList();
      

      直到我把它改成这样:

      model.Courses = db.Courses
          .Where(c => c.Track.Certification.ID == certificate)
          .ToList();
      

      再次道歉。感谢大家的意见。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多