【问题标题】:EntityFramework Unable to create a constant value of type 'Anonymous type'. Only primitive types or enumeration types are supported in this contextEntityFramework 无法创建“匿名类型”类型的常量值。此上下文仅支持原始类型或枚举类型
【发布时间】:2013-09-30 11:06:44
【问题描述】:

我正在尝试对我的实体执行ToDictionary(),但我不断收到此错误或另一个类似的错误,但消息中显示了我的实体:

无法创建“匿名类型”类型的常量值。仅有的 在此上下文中支持原始类型或枚举类型。

或者这个错误信息中有我的实体:

无法创建类型的常量值 '数据访问.帖子'。只有原始类型或 在此上下文中支持枚举类型。

我将查询分解为一些较小的和平,但仍然收到以下错误消息:

var posts = dbContext
    .Posts
    .Where(x => channels.Contains(x.Connection))
    .DistinctBy(p => new { p.Medium, p.ID })
    .OrderByDescending(x => x.Date)
    .Skip(skip)
    .Take(take);

var asociatedTags = dbContext
    .PostTagRelation
    .Where(x => posts.Any(g => g.ItemId == x.ItemId && g.Medium == x.Medium)
        && x.Company == companyId)
    .Select(x => new { x.ItemId, x.Tags })
    .ToList();

Dictionary<string, Tags> dicTags = new Dictionary<string, Tags>();
dicTags = asociatedTags.ToDictionary(g => g.ItemId, g => g.Tags);

我看到了一些关于此的帖子,但我无法将它们与我的情况联系起来。

任何帮助将不胜感激!

【问题讨论】:

  • 如果有任何问题:.DistinctBy() 是 afaik 没有开箱即用的方法。谷歌表示它带有 MoreLinq。
  • 没错,它是LINQ 的扩展。
  • DistinctBy 可能只是 LINQ-to-Objects 的扩展(即IEnumerable&lt;T&gt;,而不是IQueryable&lt;T&gt;)。这意味着,调用它会执行数据库查询,结果是内存中的posts 集合,这会导致posts.Any... 的第二个查询出现异常。此外,它会导致排序,SkipTake 在内存中执行,而不是在数据库中执行,加载的数据比您需要的多得多。我会说,避免DistinctBy
  • 如果我丢失了DistinctBy,我会收到重复的帖子。我可以用什么代替DistinctBy
  • 可能类似于:GroupBy(p =&gt; new { p.Medium, p.ID }).Select(g =&gt; g.FirstOrDefault()).

标签: c# linq entity-framework


【解决方案1】:

DistinctBy(是this one?)可能只是LINQ-to-Objects的扩展方法(即IEnumerable&lt;T&gt;,而不是IQueryable&lt;T&gt;)。这意味着,调用它会执行数据库查询,结果是内存中的posts 集合(不是IQueryable&lt;Post&gt;),这会导致posts.Any... 的第二个查询出现异常,因为对于第二个SQL 查询posts 现在是 LINQ-to-Entities 不支持的“常量”对象的集合。此外,它会导致排序,SkipTake 在内存中执行,而不是在数据库中执行,可能会产生不必要的开销,并且加载的数据比您需要的多。

您可以尝试避免使用 DistinctBy 并将其替换为以下应返回 postsIQueryable&lt;Post&gt; 的内容:

var posts = dbContext
    .Posts
    .Where(x => channels.Contains(x.Connection))
    .GroupBy(p => new { p.Medium, p.ID })
    .Select(g => g.FirstOrDefault()) // gives the first Post in each group
    .OrderByDescending(x => x.Date)
    .Skip(skip)
    .Take(take);

【讨论】:

    【解决方案2】:

    在创建匿名类之前调用​​ToList() (Select(x =&gt; new { x.ItemId, x.Tags }))

    var dicTags= dbContext.PostTagRelation
       .Where(x => posts.Any(g => g.ItemId == x.ItemId && g.Medium == x.Medium)
           && x.Company == companyId)
       //force execution of the query
       .ToList() 
       //now you have an IEnumerable instead of IQueryable
       .ToDictionary(g => g.ItemId, g => g.Tags);
    

    【讨论】:

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