简体   繁体   English

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

[英]How to use a Factory method as resultSelector in LINQ Join

I would like to use a method from my ModelFactory class to create an instance of CommentWithUserDetails instead of using an Object Initializer. 我想使用ModelFactory类中的方法来创建CommentWithUserDetails的实例,而不是使用对象初始化器。 Can this be done? 能做到吗?

ExceptionMessage 异常消息

LINQ to Entities does not recognize the method 'WebApi.Models.CommentWithUserDetails Create(WebApi.Models.Comment, WebApi.Models.ApplicationUser)' method, and this method cannot be translated into a store expression. LINQ to Entities无法识别方法'WebApi.Models.CommentWithUserDetails Create(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
        };
    }
}

Rather than having a method as a selector, you'll need to have an expression, but you can of course write a method (or property) that returns the expression that you want, so that you can use it in multiple places: 不需要使用方法作为选择器,而是需要一个表达式,但是您当然可以编写一个返回所需表达式的方法(或属性),以便可以在多个地方使用它:

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

You can then pass in ModelFactory.Create into the result selector for the Join . 然后,您可以通过在ModelFactory.Create到结果选择了Join

Yes, but. 对,但是。 By using a factory method you will only be able to use linq to objects. 通过使用工厂方法,您将只能对对象使用linq。 Query Providers will not know what to do with your factory method. 查询提供者将不知道如何使用工厂方法。 (That is what the exception you are getting is saying.) (这就是您正在说的异常。)

If you do the join first then call .AsEnumerable() then use a .Select(...) with your factory this will work. 如果您先进行连接,然后调用.AsEnumerable()然后在工厂中使用.Select(...) ,则将起作用。 You will lose composability. 您将失去可组合性。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM