There was a similar problem. ViewModels library that looks like this:
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, };
It works:
var tags = await db.Tags.Take(10).Select(TagViewModel.Select) .ToArrayAsync();
But this does not compile:
var post = await db.Posts.Take(10) .Select(p => new { Post = p, Tags = p.Tags.Select(pt => pt.Tag).Select(TagViewModel.Select) }) .ToArrayAsync();
Because the second .Select is a mess - the first one is really called from ICollection, which is not IQueryable, so it consumes this first expression as a simple Func , not Expression<Func... This returns an IEnumerable<... as described on this page. So .AsQueryable() to the rescue:
var post = await db.Posts.Take(10) .Select(p => new { Post = p, Tags = p.Tags.Select(pt => pt.Tag).AsQueryable() .Select(TagViewModel.Select) }) .ToArrayAsync();
But this creates a new, more complex problem: either I get the Internal Framework ... Error 1025, or I get the post variable with the .Post property fully loaded, but the .Tags property has an EF proxy object that seems to be used for Lazy-Loading.
The solution is to control the return type of tags by ending the use of the Anonymous class:
public class PostViewModel { public Post Post { get; set; } public IEnumerable<TagViewModel> Tags { get; set; }
Now select this and it all works:
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();
Chris Moschini Dec 21 '17 at 1:11 2017-12-21 01:11
source share