#c# #postgresql #.net-core #many-to-many #backend
#c# #postgresql #.net-ядро #многие ко многим #серверная часть
Вопрос:
У меня есть две сущности, пользователи и классы, с отношением «многие ко многим». Я работаю с .Net Core, и я установил отношения, следуя этому сообщению в блоге ЗДЕСЬ (вплоть до части 3). База данных работает, и я могу добавлять классы и заполнять таблицу соединений, но я не знаю, как получить все классы, в которых зарегистрирован пользователь, или наоборот, всех пользователей, которые зарегистрированы в определенном классе.
Мне это нужно для решения случая, когда пользователь уже зарегистрирован в классе, и мне не нужно добавлять новую запись в таблицу объединения (которая все равно выдала бы ошибку).
User.cs
public class User : IdentityUser
{
// Making the classes a JoinCollectionFacade allows us to perform actions like adding a class
public User()
=> Classes = new JoinCollectionFacade<Class, UserClass>(
UserClass,
uc => uc.Class,
c => new UserClass { User = this, Class = c });
public string FirstName { get; set; }
public string LastName { get; set; }
public string Type { get; set; }
//public string Email { get; set; }
public string Phone { get; set; }
public string Membership { get; set; }
private ICollection<UserClass> UserClass { get; } = new List<UserClass>();
// This element does not need to be mapped. It's used for easier reference
// to the Users enrolled in the class
[NotMapped]
public ICollection<Class> Classes { get; }
}
Class.cs
public class Class
{
// Making the classes a JoinCollectionFacade allows us to perform actions like adding a class
public Class()
=> Users = new JoinCollectionFacade<User, UserClass>(
UserClass,
uc => uc.User,
u => new Models.UserClass { User = u, Class = this });
public Class(Instructor i, string d)
{
Instructor = i;
Description = d;
}
public int Id { get; set; }
public virtual Instructor Instructor { get; set; } // Made virtual so we can take advantage of certain Entity Framework such as lazy loading (from Microsoft docs)
public string Description { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
private ICollection<UserClass> UserClass { get; } = new List<UserClass>();
// This element does not need to be mapped. It's used for easier reference
// to the Users enrolled in the class
[NotMapped]
public ICollection<User> Users { get; }
}
UserClass.cs
public class UserClass
{
public string UserId { get; set; }
public User User { get; set; }
public int ClassId { get; set; }
public Class Class { get; set; }
}
Комментарии:
1. По крайней мере, вы должны опубликовать эти 2 класса. Класс User должен иметь коллекцию объектов класса, поэтому, если вы запрашиваете конкретного пользователя и включаете список классов, вы получаете то, что вам нужно. Я могу только предположить, что объекты отображаются подобным образом на основе вашего описания.
2. Я отредактировал вопрос и включил свои классы.
3. Попробуйте удалить эти
NotMapped
атрибуты, и вы сможете включить их в свой запрос.4. Для меня это не решает проблему. Не могли бы вы привести мне пример запроса, который я ищу?
5. Ваша проблема в том, что вы следовали подходу какого-то блога, который не позволяет вам выполнять includes, что в точности является решением вашей проблемы. Вы можете увидеть наглядный пример здесь внизу.
Ответ №1:
Я решил свою проблему с помощью
- создание общедоступных экземпляров UserClass как в User.cs, так и в Class.cs
- используя этот вид запроса ниже, чтобы получить всех пользователей, зарегистрированных в определенном классе
var usersInClass = _context.Users
.Include(i => i.UserClass).ThenInclude(i => i.Class)
.Where(x => x.UserClass.Select(pc => pc.Class).Any(c => c.Id == id))
.ToList();