5

我正在尝试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);

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

任何帮助将不胜感激!

4

2 回答 2

4

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

您可以尝试避免DistinctBy并将其替换为以下内容,该内容应返回postsIQueryable<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);
于 2013-09-30T15:14:26.983 回答
1

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);
于 2013-09-30T11:13:00.187 回答