На самом деле я знаю, как создавать и использовать отношение «многие ко многим» в обычном контексте EF Core DB, но в своем нынешнем проекте я решил перенести мои таблицы контекста Identity DB в мой ApplicationDbContext, где я храню остальные свои бизнес-таблицы. :
public class ApplicationDbContext : IdentityDbContext<AppUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
public DbSet<CompanyModel> Companies { get; set; }
public DbSet<CompanyUser> CompaniesUsers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
//many-to-many
modelBuilder.Entity<CompanyUser>()
.HasKey(c => new { c.CompanyId, c.UserId });
/* do I realy need this at all? -> https://stackoverflow.com/a/54612387/12603542
modelBuilder.Entity<CompanyUser>()
.HasOne(cu => cu.AppUser)
.WithMany(au => au.CompaniesUsers)
.HasForeignKey(cu => cu.UserId);
modelBuilder.Entity<CompanyUser>()
.HasOne(cu => cu.CompanyModel)
.WithMany()
.HasForeignKey(cu => cu.CompanyId);
*/
}
}
У меня есть отношения, в которых у многих пользователей может быть много компаний, поэтому я создал мост между многими для многих Company <-> AppUser:
public class CompanyUser
{
public int CompanyId { get; set; }
public string UserId { get; set; }
public AppUser AppUser { get; set; }
public CompanyModel CompanyModel { get; set; }
}
И мой AppUser содержит свойство навигации:
public class AppUser : IdentityUser
{
//(...)
public ICollection<CompanyUser> CompaniesUsers { get; set; } //many-to-many
}
То же самое и в моей CompanyModel:
public class CompanyModel
{
[Key]
public int CompanyId { get; set; }
//(...)
public ICollection<CompanyUser> CompaniesUsers { get; set; } //many-to-many
}
Кажется, все в порядке, пока я не пытаюсь найти пользователя со связанными компаниями из базы данных, где мой контроллер вызывает метод DAL:
AppUser userWithLists = _repositoryUser.GetUser(user.Id);
И в моем репозитории я пытаюсь сделать это:
public AppUser GetUser(string id)
{
return _context.Users
.Include(u => u.CompaniesUsers)
.ThenInclude(u => u.CompanyModel)
.Where(u => u.Id == id)
.FirstOrDefault();
}
Но к сожалению при выполнении запроса LINQ в контексте моей БД I получаю исключение:
SqlException: недопустимое имя столбца 'AppUserId'. Неверное имя столбца 'AppUserId'.
С закомментированным кодом OnModelCreating я получаю еще одно исключение:
SqlException: Неверное имя столбца 'CompanyModelCompanyId'.
Таблица моста T- SQL код создания:
CREATE TABLE [dbo].[CompaniesUsers] (
[CompanyId] INT NOT NULL,
[UserId] NVARCHAR (450) NOT NULL,
CONSTRAINT [PK_CompaniesUsers] PRIMARY KEY CLUSTERED ([CompanyId] ASC, [UserId] ASC),
CONSTRAINT [FK_CompaniesUsers_Companies_CompanyId] FOREIGN KEY ([CompanyId]) REFERENCES [dbo].[Companies] ([CompanyId]) ON DELETE CASCADE,
CONSTRAINT [FK_CompaniesUsers_AppUser_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_CompaniesUsers_CompanyId]
ON [dbo].[CompaniesUsers]([CompanyId] ASC);