Создаваемые дубликаты внешних ключей и столбцов для идентификатора EF Core 3.1 - PullRequest
2 голосов
/ 09 июля 2020

Возникла проблема с ef core 3.1, создающим повторяющиеся столбцы для поля id из другой таблицы. В настоящее время у меня есть сущность ApplicationUser, которая наследуется от IdentityUser, и сущность свойства, которая хранит идентификатор ApplicationUser как UserId.

 public class Property
    {
        public Guid PropertyId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public Guid AddressId { get; set; }
        public Address PropertyAddress { get; set; }
        public bool IsHome { get; set; }
        public string UserId { get; set; }
        public ApplicationUser User { get; set; }
    }
public class ApplicationUser : IdentityUser
    {
        public IEnumerable<Property> properties { get; set; }
    }
public class PropertyConfig : IEntityTypeConfiguration<Property>
    {
        public void Configure(EntityTypeBuilder<Property> builder)
        {
            builder.HasKey(p => p.PropertyId);
            builder.HasOne(p => p.PropertyAddress).WithOne();
            builder.HasOne(p => p.User).WithMany(p => p.properties).HasForeignKey(f => f.UserId).OnDelete(DeleteBehavior.Restrict);
        }
    }
 public class ApplicationUserConfig : IEntityTypeConfiguration<ApplicationUser>
    {
        public void Configure(EntityTypeBuilder<ApplicationUser> builder)
        {
            builder.ToTable("User");
            builder.HasKey(p => p.Id);
            builder.HasMany<Property>().WithOne(p => p.User).HasForeignKey(f => f.UserId);
        }
    }

Выше мои классы, и я запустил миграция, которая создает эту таблицу для свойства.

migrationBuilder.CreateTable(
                name: "Property",
                columns: table => new
                {
                    PropertyId = table.Column<Guid>(nullable: false),
                    Name = table.Column<string>(nullable: true),
                    Description = table.Column<string>(nullable: true),
                    AddressId = table.Column<Guid>(nullable: false),
                    IsHome = table.Column<bool>(nullable: false),
                    UserId = table.Column<string>(nullable: true),
                    ApplicationUserId = table.Column<string>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Property", x => x.PropertyId);
                    table.ForeignKey(
                        name: "FK_Property_Address_AddressId",
                        column: x => x.AddressId,
                        principalTable: "Address",
                        principalColumn: "AddressId",
                        onDelete: ReferentialAction.Cascade);
                    table.ForeignKey(
                        name: "FK_Property_User_ApplicationUserId",
                        column: x => x.ApplicationUserId,
                        principalTable: "User",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Restrict);
                    table.ForeignKey(
                        name: "FK_Property_User_UserId",
                        column: x => x.UserId,
                        principalTable: "User",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Restrict);
                });

Как видите, создается правильный столбец UserId и внешний ключ. но он также создает ApplicationUserId, и я не могу понять, что его вызывает.

Любая идея?

Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

2 голосов
/ 09 июля 2020

В вашей текущей конфигурации API

public void Configure(EntityTypeBuilder<ApplicationUser> builder) {
    builder.HasMany<Property>()
        .WithOne(p => p.User)
        .HasForeignKey(f => f.UserId);
}

Вы просто говорите, что существует отношение «один ко многим» между сущностями ApplicationUser и Property, но не то, какие члены задействованы из много сторона. Действительно, между Property ApplicationUser.

может быть несколько ассоциаций. Чтобы заставить его работать, укажите участников, задействованных на обоих концах, настроив вашу конфигурацию следующим образом

public void Configure(EntityTypeBuilder<ApplicationUser> builder) {
    builder.HasMany(u => u.properties)
        .WithOne(p => p.User)
        .HasForeignKey(f => f.UserId);
}
0 голосов
/ 09 июля 2020

Это потому, что у вас есть оба:

  public string UserId { get; set; }
  public ApplicationUser User { get; set; }

Если вы не хотите User ссылаться на таблицу User, вам придется проигнорировать ее. Что-то вроде этого (я не могу вспомнить, точный ли это синтаксис)

   builder.Property(p => p.User).Ignore();

Но это означает, что при извлечении Property из контекста User будет нулевым. Также, если вы прикрепите ApplicationUser к Property, а затем сохраните свойство - ни User, ни отношение не будут записаны в базу данных, и вам нужно будет установить UserId вручную.

...