Linq Многие ко многим в ядре Entity Framework - PullRequest
0 голосов
/ 29 января 2019

У меня есть классы для построения отношений многие ко многим.

public class Chat 
{
    [Key]
    public Guid Id { get; set; }
    public ICollection<ApplicationUserChat> UserChats { get; set; }
}

public class ApplicationUserChat
{
    [Required]
    public string UserId { get; set; }
    public ApplicationUser User { get; set; }

    public Guid ChatId { get; set; }
    public Chat Chat { get; set; }
}

public class ApplicationUser : IdentityUser
{        
    public ICollection<ApplicationUserChat> UserChats { get; set; }       
}

Например, у меня есть user1 и user2

  1. Мне нужно выбрать чаты дляuser1, где чат содержит user2
  2. Мне нужно выбрать чат для user1, где чат содержит user2 и не содержит других пользователей (например, один чат содержит только 2 участника)

    Как я могу сделать это в EF Core через один запрос к БД?

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Если допустимо выполнить 2 запроса к базе данных, чтобы получить данные для обоих случаев, вы можете использовать следующие запросы

//chats that contain user1 and user2
var chats1 = context
    .Chats
    .Where(c => c.UserChats.Any(u => u.UserId == userId1))
    .Where(c => c.UserChats.Any(u => u.UserId == userId2))
    .ToList();

//chats that contain user1 and user2 and they are only users in chat
var chats2 = context
    .Chats
    .Where(c => c.UserChats.Any(u => u.UserId == userId1))
    .Where(c => c.UserChats.Any(u => u.UserId == userId2))
    .Where(c => c.UserChats.Count() == 2)
    .ToList();

Если вы хотите получить все данные в 1 запросе, вы можете объявить новый класс, который содержитнеобходима информация о чате

public class ChatDto
{
    public Guid Id { get; set; }

    public int UserCount { get; set; }
}

и выполните следующий запрос

var chats = context
    .Chats
    .Where(c => c.UserChats.Any(u => u.UserId == userId1))
    .Where(c => c.UserChats.Any(u => u.UserId == userId2))
    .Select(c => new ChatDto
    {
        Id = c.Id,
        UserCount = c.UserChats.Count()
    })
    .ToList();

Поэтому у вас будут чаты, содержащие user1 и user2 и всегоколичество пользователей в чате.

0 голосов
/ 29 января 2019
 var chats = user1.UserChats.Select(uc => uc.ChatId).Distinct();
 var result1 = context.ApplicationUserChat
       .Where(a => a.UserId == user2.Id && chats.Contains(a.ChatId))
       .Select(a => a.Chat)
       .ToList();
 var result2 = results1.Except(context.ApplicationUserChat
       .Where(a => a.UserId != user2.Id 
                   && a.UserId != user2.Id 
                   && chats.Contains(a.ChatId))
       .Select(a => a.Chat)
       .Distinct())
       .ToList();

// загрузка ... короткой версии с использованием /, если у вас уже есть списки пользователей:

 var result1 = user1.UserChat.Intersect(user2.UserChats);
...