EF Core 2.1 - дублирующиеся отношения при использовании свободного API - PullRequest
0 голосов
/ 23 октября 2018

Я разрабатываю веб-API с .NET Core 2.1 и EF Core.Но у меня есть проблема с моим ApplicationDbContext, который я не понимаю.У меня есть 2 таблицы (пользователи и профили, одна ко многим), профиль внешнего ключа в таблице пользователя не требуется.

При использовании Fluent API, когда я объявляю свои отношения, ef core создает дублированный внешний ключ на том же самомссылка, но почему?

Вот мой userModel:

public class UserModel
{
    public long Id { get; set; }

    public string Username { get; set; }

    public string Password { get; set; }

    public DateTime DateAdded { get; set; }

    public DateTime? DateUpdated { get; set; }

    public DateTime? DateLastConnection { get; set; }

    public long? ProfileId { get; set; }

    public ProfileModel Profile { get; set; }
}

public class UserModelConfiguration : IEntityTypeConfiguration<UserModel>
{
    public void Configure(EntityTypeBuilder<UserModel> builder)
    {
        builder.ToTable("USR_USER");

        builder.Property(table => table.Id).HasColumnName("ID").HasColumnType("bigint").UseSqlServerIdentityColumn();
        builder.Property(table => table.Username).HasColumnName("USERNAME").HasColumnType("nvarchar(20)").HasMaxLength(20).IsRequired();
        builder.Property(table => table.Password).HasColumnName("PASSWD").HasColumnType("nvarchar(200)").HasMaxLength(200).IsRequired();
        builder.Property(table => table.DateAdded).HasColumnName("DATE_ADDED").HasColumnType("datetime").IsRequired().IsRequired();
        builder.Property(table => table.DateUpdated).HasColumnName("DATE_UPDATED").HasColumnType("datetime");
        builder.Property(table => table.DateLastConnection).HasColumnName("LAST_CONNECTION").HasColumnType("datetime");
        builder.Property(table => table.ProfileId).HasColumnName("PROFILE_ID").HasColumnType("bigint");

        builder.HasKey(table => table.Id);
        builder.HasAlternateKey(table => table.Username);

        builder.HasOne<ProfileModel>()
            .WithMany(p => p.Users)
            .HasForeignKey(u => u.ProfileId);
    }
}

Вот мой ProfileModel:

public class ProfileModel
{
    public long Id { get; set; }

    public string Name { get; set; }

    public string Description { get; set; }

    public ICollection<UserModel> Users { get; set; }

    public ICollection<ProfileRoleModel> ProfileRoles { get; set; }
}

public class ProfileModelConfiguration : IEntityTypeConfiguration<ProfileModel>
{
    public void Configure(EntityTypeBuilder<ProfileModel> builder)
    {
        builder.ToTable("USR_PROFILE");

        builder.Property(p => p.Id).HasColumnName("ID").HasColumnType("bigint").UseSqlServerIdentityColumn();
        builder.Property(p => p.Name).HasColumnName("PROFILE_NAME").HasColumnType("nvarchar(20)").HasMaxLength(20).IsRequired();
        builder.Property(p => p.Description).HasColumnName("PROFILE_DESCRIPTION").HasColumnType("nvarchar(200)").HasMaxLength(200).IsRequired();

        builder.HasKey(p => p.Id);
    }
}

Вот мой контекст приложения:

public class ApplicationDbContext : DbContext
{
    public ApplicationDbContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<UserModel> Users { get; set; }

    public DbSet<ProfileModel> Profiles { get; set; }

    public DbSet<ProfileRoleModel> ProfileRoles { get; set; }

    public DbSet<RoleModel> Roles { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new UserModelConfiguration());
        modelBuilder.ApplyConfiguration(new ProfileModelConfiguration());
        modelBuilder.ApplyConfiguration(new ProfileRoleModelConfiguration());
        modelBuilder.ApplyConfiguration(new RoleModelConfiguration());
    }
}

ИВ результате миграции, как видите, существует два внешних ключа.Из-за этого, когда я запрашиваю моего пользователя DbSet, у меня появляется ошибка sql «Неизвестный столбец ProfileId1»

CREATE TABLE [USR_PROFILE] (
    [ID] bigint NOT NULL IDENTITY,
    [PROFILE_NAME] nvarchar(20) NOT NULL,
    [PROFILE_DESCRIPTION] nvarchar(200) NOT NULL,
    CONSTRAINT [PK_USR_PROFILE] PRIMARY KEY ([ID])
);

GO

CREATE TABLE [USR_USER] (
             [ID] bigint NOT NULL IDENTITY,
             [USERNAME] nvarchar(20) NOT NULL,
             [PASSWD] nvarchar(200) NOT NULL,
             [DATE_ADDED] datetime NOT NULL,
             [DATE_UPDATED] datetime NULL,
             [LAST_CONNECTION] datetime NULL,
             [PROFILE_ID] bigint NULL,
             [ProfileId1] bigint NULL,
             CONSTRAINT [PK_USR_USER] PRIMARY KEY ([ID]),
             CONSTRAINT [AK_USR_USER_USERNAME] UNIQUE ([USERNAME]),
             CONSTRAINT [FK_USR_USER_USR_PROFILE_PROFILE_ID] FOREIGN KEY ([PROFILE_ID]) REFERENCES [USR_PROFILE] ([ID]) ON DELETE NO ACTION,
             CONSTRAINT [FK_USR_USER_USR_PROFILE_ProfileId1] FOREIGN KEY ([ProfileId1]) REFERENCES [USR_PROFILE] ([ID]) ON DELETE NO ACTION
    );

    GO

Та же проблема с другим моим DbSet, но я думаю, что это аналогичная проблема.

Iосновали мою конфигурацию на этой документации Полностью определенные отношения

1 Ответ

0 голосов
/ 23 октября 2018

Это потому, что у вас есть свойство навигации

public ProfileModel Profile { get; set; }

, но в плавной конфигурации

builder.HasOne<ProfileModel>()

вы говорите EF, что это не является частью этих отношений.Следовательно, EF традиционно отображает его в другое отдельное отношение с автоматически сгенерированным именем FK.

Вы всегда должны использовать перегрузки метода Has / With, которые представляют наличие / отсутствие свойства навигации в соответствующем концесвязь.

В вашем случае замените вышеприведенное на

builder.HasOne(u => u.Profile)

, и проблема будет решена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...