EF Core 2.1-使用流畅的API时重复关系 [英] EF Core 2.1 - Duplicate relationships when use fluent API

查看:82
本文介绍了EF Core 2.1-使用流畅的API时重复关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用.NET Core 2.1和EF Core开发了一个Web API。
但是我的ApplicationDbContext有一个我不明白的问题。
我有2个表(用户和个人资料,一对多),不需要User表中的外键个人资料。

I develop a web API with .NET Core 2.1 and EF Core. But i have a problem with my ApplicationDbContext that i don't understand. I have 2 tables (Users and Profiles, one to many), the foreign key profile in User table is not required.

使用Fluent API,当我声明我的关系,ef core在同一引用上创建重复的外键,但是为什么呢?

With Fluent API, when i declare my relationships, ef core create duplicate foreign key on the same reference, but why ?

这是我的userModel:

Here is my 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:

Here is my 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);
    }
}

这是我的应用程序上下文:

Here is my application context :

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错误'Unknown column ProfileId1'

And the migrations result, as you can see, there is two foreign keys. Because of that, when i query my DbSet User i have an sql error 'Unknown column 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有相同的问题,但我认为这是相似的问题。

Same problem with my other DbSet but i think it's a similar problem.

我的配置基于此文档完全定义的关系

推荐答案

这是因为您具有导航属性

It's because you have navigation property

public ProfileModel Profile { get; set; }

但使用流畅的配置

builder.HasOne<ProfileModel>()

您在告诉EF这不是那种关系的一部分。因此,按照惯例,EF会将其映射到具有自动生成的FK名称的另一个单独的关系。

you are telling EF that it's not a part of that relationship. Hence EF conventionally maps it to another separate relationship with automatically generated FK name.

您应始终使用 Has / With 方法重载,表示关系的相应末端是否存在导航属性。

You should always use the Has / With method overloads which represent the presence/absence of a navigation property at the corresponding end of the relationship.

在您的情况下,将上面的内容替换为

In your case, replace the above with

builder.HasOne(u => u.Profile)

问题将得到解决。

这篇关于EF Core 2.1-使用流畅的API时重复关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆