Фильтр с левым соединением в Entity Framework - PullRequest
1 голос
/ 01 февраля 2020

У меня есть User, Contact и ContactOfUser сущностей в ASP. NET Core API проекте. Я хочу отфильтровать пользователей по данным этих таблиц.

Мои классы сущностей таковы:

    public class User
    {
        public int Id { get; set; }

        [MaxLength(50)]
        public string Name { get; set; }

        [MaxLength(50)]
        public string Surname { get; set; }

        [MaxLength(60)]
        public string Username { get; set; }
}

public class Contact
{
    public int Id { get; set; }

    [MaxLength(50)]
    public string Value{ get; set; }
}

public class ContactOfUser
{
    public int Id { get; set; }

    public int UserId { get; set; }
    [ForeignKey(nameof(UserId))]
    public User User { get; set; }

    public int ContactId { get; set; }
}

Я хочу получить отфильтрованных пользователей на основе этого FilterModel объекта:

public class FilterModel
{
     public string Name { get; set; }
     public string Surname { get; set; }
     public string Username { get; set; }
     public List<int> ContactId { get; set; }
}

Как я могу сделать это процесс фильтрации в Entity Framework с методами Linq, учитывая, что не применяются специальные данные фильтра, когда эти данные будут приняты как нулевые?

Я сделал что-то подобное этому методу, но он не работает должным образом:

List<User> GetFilteredUsers(FilterModel filter)
{
    var query1 = dbContext.Users
                          .Where(u => u.Name.Contains(filter.Name ?? string.Empty) &&
                                      u.Surname.Contains(filter.Surname ?? string.Empty) &&
                                      u.Username.Contains(filter.Username ?? string.Empty));

    var query2 = from u in query1
                 join cu in dbContext.ContactOfUsers on u.Id equals cu.UserId
                 into res
                 from item in res.DefaultIfEmpty()
                 where filter.Contacts.Contains(item.ContactId)
                 select new InitialUserModel
                         {
                             Id = u.Id,
                             Name = u.Name,
                             Surname = u.Surname,
                             Username = u.Username
                         };
}

1 Ответ

1 голос
/ 01 февраля 2020

Вы можете достичь этого следующим образом

  • Используя GroupBy для получения userId и ContactIds соответственно.
var userContactIds = _dbContext.ContactOfUser.GroupBy(p => p.UserId).Select(g => new { UserId = g.UserId,  ContactIds = g.Select(p => p.ContactId).ToList() });
  • Получите результат:
var result = _dbContext.User.Select(p => new FilterModel 
{ 
   Name = p.Name, Surname = p.Surname, Username = p.Username, 
   ContactId = userContactIds.Where(c => p.Id == c.UserId).ToList() 
});

Обновлено

List<User> GetFilteredUsers(FilterModel filter)
{
     return (from u in _dbContext.User
            join c in _dbContext.ContactOfUser on u.Id equals c.UserId
            join fContactId in filter.ContactId on c.ContactId equals fContactId 
            where u.Name == filter.Name && u.Surname == filter.Surname && u.Username == filter.Username 
            select u).ToList();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...