LINQ to Entities - Selecione todos os utilizadores amigos e bate-Papo entre eles

0

Pergunta

Como posso Selecionar todos os amigos do usuário conectado no momento e o Privado, Chats (bate-Papo Id) entre o usuário e seus amigos? Eu sou capaz de superar o usuário amigos, mas estou tendo problemas para também obter o bate-Papo entre eles.

            // Select all the User's friends and the chat (Id) between them
            var friends = await _context.Friendships // Get the Friendships
                .Include(x => x.Friend).ThenInclude(x => x.ChatUsers).ThenInclude(x => x.Chat)
                .Where(x => x.Status == StatusCode.Accepted && x.ApplicationUserId == userId)
                .Select(x => x.Friend)
                .ToListAsync();

Amizade tabela

    public class Friendship
    {
        // The primary keys/foreign keys of the associated tables
        public string ApplicationUserId { get; set; }
        public string ApplicationFriendUserId { get; set; }

        // Reference to the user that has the friend
        public User ApplicationUser { get; set; }

        // Reference to the friend
        public User Friend { get; set; }

        // The status of the friendship
        public StatusCode Status { get; set; }
    }

Tabela de usuário

    public class User : IdentityUser
    {
        // Reference to all user's chats
        public ICollection<ChatUser> ChatUsers { get; set; }

        // Reference to all the user's friendships
        public ICollection<Friendship> UsersFriendships { get; set; }

        // Reference to all the friend's friendships (their point of view)
        public ICollection<Friendship> FriendsFriendships { get; set; }
    }

ChatUser tabela

    public class ChatUser
    {
        // The primary key/foreign keys of the associated tables
        public int ChatId { get; set; }
        public string UserId { get; set; }

        // The role that the User can be
        public UserRole Role { get; set; }

        // Reference to the chat
        public Chat Chat { get; set; }

        // Reference to the user
        public User User { get; set; }
    }

Bate-papo

    
    public class Chat
    {
        // The primary key
        public int Id { get; set; }

        // The chat's name
        public string Name { get; set; }

        // The chat type, e.g room, private
        public ChatType Type { get; set; }

        // Reference to all the Chat's Users
        public ICollection<ChatUser> ChatUsers { get; set; }
    }

Obrigado

1

Melhor resposta

1

Esta consulta:

var friends = await _context.Friendships // Get the Friendships
    .Include(x => x.Friend).ThenInclude(x => x.ChatUsers).ThenInclude(x => x.Chat)
    .Where(x => x.Status == StatusCode.Accepted && x.ApplicationUserId == userId)
    .Select(x => x.Friend)
    .ToListAsync();

... carrega o usuário amigos com os amigos correspondente conversas que incluem conversas não com o usuário atual.

Com essa estrutura de domínio para os chats e as amizades ele parece um pouco complicado para tentar vinculá-los em uma forma significativa. É provável possível com uma simples abordagem de dois passos:

var friendIds = _context.Users
    .Where(x => s.UserId == userId)
    .SelectMany(x => x.UsersFriendships.Where(f => f.Status == StatusCode.Accepted).Select(f => f.ApplicationFriendUserId))
    .ToList(); // Get all accepted Friend IDs.


 var chats = _context.Chats
     .Where(x => x.ChatUsers.Any(cu => cu.UserId) && x => x.ChatUsers.Any(cu => friendIds.Contains(cu.UserId)
     .Select(x => new 
     {
         Chat = x,
         Friends = x.ChatUsers.Where(cu => friendIds.Contains(cu.UserId)).Select(cu => cu.User).ToList()
      }).ToList();

Bate-papos estão relacionados a dois ou mais usuários, e eles não são restritos/vinculada ao amizades.

Joe poderia ser amigo de Sam, Joana, João e têm as seguintes bate-papos ativos:

Bate-Papo 1: Joe <-> Sam

Bate-Papo 2: Joe <-> Jane

Bate-Papo 3: Joe <-> Jane <-> Sam

Bate-Papo 4: Joe <-> Frank

Bate-Papo 5: Joe <-> Frank <-> Sam

Nós queremos Chats 1, 2, 3, e 5 devolvidos. Não há conversas com o João, e nós não nos preocupamos com o bate-papo com Frank, mas não preocupam um com Frank & Sam desde que Sam é um amigo. O objetivo seria identificar quais os bate-papos que Joe está a participar com um ou mais de seus amigos. Para cada encontro, voltamos a conversar e Amigos, neste momento também em que o bate-papo.

A limitação da abordagem de dois passos é que ele assume que a lista de amigos permanecem razoavelmente pequena, não é grande o suficiente para exceder o IN() lista que seria gerado para obter a correspondência de bate-Papos.

2021-11-23 04:50:49

Em outros idiomas

Esta página está em outros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................