Итак, я изучаю ASP.Net и EF Core и решил попутно сделать проект. Решил сделать простенькую социальную сеть.
Итак, вот три модели, которые мне нужно связать (не полные модели, я показываю только необходимые реквизиты):
public class User : IdentityUser
{
public List<GroupChat> GroupChats { get; set; } // nav prop that leads to this user's group chats
}
public class GroupChat
{
public List<GroupChatUser> Members { get; set; } // nav prop that leads to this gc members
}
public class GroupChatUser
{
public User User { get; set; } // nav prop that leads to the global user
public GroupChat GroupChat { get; set; } // nav prop that leads to the gc of this member
public string PermissionGroup { get; set; } // e.g. Administrator, Moderator, Default
}
Итак, вот все данные, необходимые для ответа на этот вопрос. Очевидно, у этих моделей есть другие данные, поэтому я не могу просто использовать List<User> Members
, потому что у GroupChatUser
есть другие данные, связанные с этим чатом. Пользователи предназначены для всего приложения (они содержат, например, адреса электронной почты, пароли и т. д.), а GroupChatUsers — для одного группового чата (они содержат, например, разрешения (роли) для этого конкретного пользователя в этом конкретном групповом чате, псевдонимы и т. д.) .
Как вы, наверное, понимаете, я не смог определить отношения для приведенных выше моделей, потому что для определения отношения "многие ко многим" необходимо List<User> Members
.
Но ясно, что существует только один GroupChatUser для определенного пользователя в определенном групповом чате, поэтому должен быть способ определить отношения, подобные этому: GroupChat <-> GroupChatUser <-> User
, и он должен быть прозрачным, чтобы я может получить доступ к групповым чатам от пользователя напрямую.
Поэтому прямо сейчас мне нужно прибегнуть к определению List<GroupChatUser> GroupChatUsers
в модели пользователя, а затем получить доступ к свойству GroupChat
пользователя GroupChatUser, что неплохо, но также не очень удобно.
Надеюсь, я все правильно описал.
Чтобы прояснить ситуацию, я хочу иметь возможность писать такой код (полупсевдокод):
User user = _dbContext.Users
// All the necessary Includes/ThenIncludes/Selects. Imagine that all the necessary data is projected successfully.
.FirstOrDefault(...); // We got the current logged in user with all necessary properties loaded
foreach (GroupChat groupChat in user.GroupChats) {
Console.WriteLine($"User '{user.UserName}' has a group chat with title '{groupChat.Title}'");
Console.WriteLine($"It has {groupChat.Members.Count} members: ");
foreach (GroupChatUser member in groupChat.Members) {
Console.WriteLine($" - {member.User.UserName}: Group = '{member.PermissionGroup}'");
}
}
Этот код может привести к следующим результатам:
User 'AdminTestAccount' has a group chat with title 'First Group Chat in this social network'
It has 3 members:
- AdminTestAccount: Group = Administrators
- John_Travis: Group = Default
- jbdxcz12431: Group = Default
User 'AdminTestAccount' has a group chat with title 'Support Chat'
It has 7 members:
- AdminTestAccount: Group = Administrators
- John_Travis: Group = Moderators
- jbdxcz12431: Group = Moderators
- SuperUser123: Group = Default
- mike_harris_1983: Group = Default
- abcdefgh123: Group = Default
- not_admin1341: Group = Default
Как видите, John_Travis является По умолчанию в одном GroupChat и Модератором в другом. То, что я не смог воспроизвести с List<User> Members
в GroupChat.
Надеюсь, это "разъяснение" не усложнит вопрос еще больше.