EF Core IdentityUser во многих отношениях с бизнес-моделью, как использовать .Include (). ThenInclude ()? - PullRequest
0 голосов
/ 06 февраля 2020

На самом деле я знаю, как создавать и использовать отношение «многие ко многим» в обычном контексте 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);
...