如何在LINQ Join中将Factory方法用作resultSelector

时间:2016-10-05 21:00:14

标签: c# linq

我想使用我的ModelFactory类中的方法来创建CommentWithUserDetails的实例,而不是使用Object Initializer。可以这样做吗?

  

ExceptionMessage

     

LINQ to Entities无法识别该方法   ' WebApi.Models.CommentWithUserDetails创建(WebApi.Models.Comment,   WebApi.Models.ApplicationUser)'方法,这个方法不能   翻译成商店表达。

public IEnumerable<CommentWithUserDetails> GetAllPostComments(int postId)
    {
        var commentsWithUserDetails = _context.Comments.Join(_context.Users,
            c => c.UserId,
            u => u.Id,
            (comment, user) => _modelFactory.Create(comment, user));

        return commentsWithUserDetails;
    }
public class ModelFactory
{
    public CommentWithUserDetails Create(Comment comment, ApplicationUser user)
    {
        return new CommentWithUserDetails
        {
            Id = comment.Id,
            PostId = comment.PostId,
            Body = comment.Body,
            Name = user.Name
        };
    }
}

2 个答案:

答案 0 :(得分:3)

您不需要将方法作为选择器,而是需要有一个表达式,但您当然可以编写一个返回所需表达式的方法(或属性),以便您可以在多个地方:

public class ModelFactory
{
    public Expression<Func<Comment, ApplicationUser, CommentWithUserDetails>> Create()
    {
        return (comment, user) => new CommentWithUserDetails
        {
            Id = comment.Id,
            PostId = comment.PostId,
            Body = comment.Body,
            Name = user.Name
        };
    }
}

然后,您可以将ModelFactory.Create传递到Join的结果选择器。

答案 1 :(得分:0)

是的,但是。通过使用工厂方法,您将只能使用linq到对象。查询提供程序不知道如何处理工厂方法。 (这就是你得到的例外情况。)

如果您先进行加入,请致电.AsEnumerable(),然后在您的工厂使用.Select(...)即可。你将失去可组合性。

public IEnumerable<CommentWithUserDetails> GetAllPostComments(int postId)
{
    var commentsWithUserDetails = _context.Comments.Join(_context.Users,
        c => c.UserId,
        u => u.Id,
        (comment, user) => new { User = user, Comment = comment})
        .AsEnumerable()
        .Select(i=>_modelFactory.Create(i.Comment, i.User))
        ;

    return commentsWithUserDetails;
}