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

时间:2013-09-30 11:06:44

标签: c# linq entity-framework

我正在尝试在我的实体上执行ToDictionary(),但我一直收到此错误或其他类似的错误但是我的实体显示在消息中:

  

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

或者我的实体在错误消息中的这个:

  

无法创建类型的常量值   'DataAccess.Posts'。只有原始类型或   在此上下文中支持枚举类型。

我把查询打破了一些较小的和平,但仍然得到这些错误信息之一:

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);

我发现了一些关于此事的帖子,但我不能把它们放在我的情况中。

真的很感激任何帮助!

2 个答案:

答案 0 :(得分:4)

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

您可以尝试避免DistinctBy并将其替换为以posts作为IQueryable<Post>返回的以下内容:

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);

答案 1 :(得分:0)

在创建匿名类(ToList())之前执行Select(x => 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);