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

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

我看到了一些关于这个问题的帖子,但是它们与我的情况不符。

非常感谢任何帮助!


如果有任何关系的话:.DistinctBy() 据我所知不是一个开箱即用的方法。谷歌说它随 MoreLinq 一起提供。 - Marco
是的,它是基于“LINQ”的扩展。 - Yustme
如果我失去了“DistinctBy”,我会得到重复的帖子。我可以使用什么来代替“DistinctBy”? - Yustme
可能是这样的:GroupBy(p => new { p.Medium, p.ID }).Select(g => g.FirstOrDefault()) - Slauma
我每次选择20条记录。此外,在GroupBy()之后,我无法按x.Date排序,因为我会收到一个编译器错误,指出“System.Linq.IGrouping.......不包含'Date'的定义,也没有扩展方法......你是否缺少引用?” - Yustme
显示剩余3条评论
2个回答

4
DistinctBy(是这个?)可能只是用于LINQ-to-Objects的扩展方法(即用于IEnumerable<T>而不是IQueryable<T>)。这意味着调用它会执行DB查询到此点,并且结果是内存中的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
在创建匿名类(Select(x => new { x.ItemId, x.Tags }))之前调用ToList()方法。
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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接