遇到了类似的问题。ViewModel 库看起来像这样:
public class TagViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public static Expression<Func<SiteTag, TagViewModel>> Select = t => new TagViewModel
{
Id = t.Id,
Name = t.Name,
};
这个有效:
var tags = await db.Tags.Take(10).Select(TagViewModel.Select)
.ToArrayAsync();
但是,这段代码无法编译:
var post = await db.Posts.Take(10)
.Select(p => new {
Post = p,
Tags = p.Tags.Select(pt => pt.Tag).Select(TagViewModel.Select)
})
.ToArrayAsync();
因为第二个.Select
很混乱 - 第一个实际上是从ICollection调用的,它不是IQueryable,因此它将第一个表达式作为普通的Func
而不是Expression<Func...
消耗掉了。这将返回IEnumerable<...
,如本页所讨论的。因此,.AsQueryable()
来拯救:
var post = await db.Posts.Take(10)
.Select(p => new {
Post = p,
Tags = p.Tags.Select(pt => pt.Tag).AsQueryable()
.Select(TagViewModel.Select)
})
.ToArrayAsync();
但这会创建一个新的、更奇怪的问题:要么我得到内部框架...错误1025,要么我得到带有完全加载的.Post
属性的帖子变量,但是.Tags
属性具有似乎用于延迟加载的EF代理对象。
解决方案是通过结束使用匿名类来控制Tags的返回类型:
public class PostViewModel
{
public Post Post { get; set; }
public IEnumerable<TagViewModel> Tags { get; set; }
现在选择这个,一切都可以正常工作:
var post = await db.Posts.Take(10)
.Select(p => new PostViewModel {
Post = p,
Tags = p.Tags.Select(pt => pt.Tag).AsQueryable()
.Select(TagViewModel.Select)
})
.ToArrayAsync();
Linq2Objects
操作表达式树,这意味着你通常会传递Expression<Func<Reservation, bool>> predicate
而不是裸的Func<Reservation, bool> predicate
。你可以尝试一下。 :) - Patryk Ćwiek