2016-10-05 2 views
0

Я хотел бы использовать метод из моего класса ModelFactory для создания экземпляра CommentWithUserDetails вместо использования Object Initializer. Это можно сделать?Как использовать метод Factory как resultSelector в LINQ Join

ExceptionMessage

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

ответ

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.

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; 
} 
Смежные вопросы