#.net #entity-framework #entity-framework-core
#.net #entity-framework #entity-framework-core
Вопрос:
Сущность «Пользователь» имеет отношение «один ко многим» к сущности «Член группы».
public class User
{
#region Public properties
[Key]
[Column("id")]
public int Id { get; set; }
...
public virtual ICollection<GroupMember> GroupMembers { get; set; }
public virtual ICollection<Profile> Profiles { get; set; }
#endregion
}
public class GroupMember
{
#region Public properties
[Required]
[Column("groupid")]
public int GroupId { get; set; }
public virtual Group Group { get; set; }
[Required]
[Column("userid")]
public int UserId { get; set; }
public virtual User User { get; set; }
[Required]
[Column("lu_user")]
public int LuUser { get; set; }
[Required]
[Column("lu_date")]
public DateTime LuDate { get; set; }
#endregion
}
В классе UserDbContext я настроил связь следующим образом:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<GroupMember>()
.HasKey(x => x.UserId);
modelBuilder.Entity<GroupMember>()
.HasOne(x => x.User)
.WithMany(x => x.GroupMembers)
.HasForeignKey(x => x.UserId);
}
При выполнении запроса:
var user = _dbContext.Users
.Include(u => u.Profiles)
.Include(u => u.GroupMembers)
.ThenInclude(gm => gm.Group)
.Where(u => u.Id == id)
.Select(u => u)
.SingleOrDefault();
Поле «Члены группы» должно содержать семь записей. Результатом запроса является одна запись для поля «Члены группы».
Я не понимаю, почему я не получаю правильное количество записей для отношения.
Ответ №1:
С помощью этого свободного API
modelBuilder.Entity<GroupMember>()
.HasKey(x => x.UserId);
вы сообщаете EF, что UserId
столбец GroupMember
таблицы уникален, что делает связь фактически однозначной. Вот почему вы получаете только одну запись на пользователя, даже если у вас есть свойство навигации по коллекции.
Поскольку GroupMember
объект выглядит как объект объединения, используемый в отношениях «многие ко многим» (которые, как мы знаем, могут быть просмотрены как многие отношения «один ко многим»), скорее всего, ему нужен составной первичный ключ, например
modelBuilder.Entity<GroupMember>()
.HasKey(x => new { x.GroupId, x.UserId });
Этого должно быть достаточно, если вы сопоставляете существующую базу данных (поскольку вы ожидаете несколько записей из запроса, следовательно, вы знаете, что таблица существует и содержит несколько записей для каждого пользователя, что было бы невозможно, если UserId
бы она была уникальной).
Но на всякий случай, если вы используете подход code first с миграциями, обязательно создайте и примените новую миграцию после выполнения вышеуказанного изменения.
Комментарии:
1. Большое вам спасибо за то, что помогли мне понять проблему.
Ответ №2:
Пожалуйста, не создавайте / не устанавливайте DbContext самостоятельно. Используйте команду Scaffold-Dbcontext для автоматического создания DbContext для вас.
Scaffold-DbContext "Server=(localdb)mssqllocaldb;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models