Как присвоить имя внешнему ключу в ядре Entity Framework

#entity-framework-core #attributes #foreign-keys #fluent

#entity-framework-core #атрибуты #внешние ключи #свободно

Вопрос:

Похоже, что ядро Entity Framework не учитывает пользовательское имя внешнего ключа, которое я указал в качестве атрибута свойства. Я немного обеспокоен, потому что я думал, что это изначально сработало..

отношение 1 ко многим между CollectionModel и ItemModel (упрощенный пример):

 [Table("Collections")]
public class CollectionModel
{
    [Key]
    public int Id { get; set; }
    
    public string name {get; set; }
    
    public List<ItemModel> Items { get; set; }
}

[Table("Items")]
public class ItemModel
{
    [Key]
    public int Id { get; set; }
    
    [ForeignKey("FK_Item_CollectionId")] // No sure if it actually respects the convention..
    public int CollectionId { get; set; }
}
  

В принципе, это соответствует этому примеру (хотя Entity Framework 6). Я уже сталкивался с некоторыми потоками stackoverflow, которые используют некоторые Fluent API, но предпочел бы избегать их (т. Е. У меня есть некоторые другие проблемы ..) Когда я переношу домен (который находится в отдельном проекте от Entity Framework) Я получаю следующее имя FK_Items_Collections_ItemModelId , которое слишком длинное.

Я что-то упускаю?

Спасибо за любую информацию.

Ответ №1:

Это неправильный способ использования аннотаций для создания внешнего ключа. Вы должны создать что-то вроде этого:

 [Table("Collections")]
public class CollectionModel
{
    [Key]
    public int Id { get; set; }
    
    public string name {get; set; }
    
    [ForeignKey("FK_Item_CollectionId")]
    public List<ItemModel> Items { get; set; }
}

[Table("Items")]
public class ItemModel
{
    [Key]
    public int Id { get; set; }
    
    
    public int FK_Item_CollectionId { get; set; }
}
  

Ответ №2:

В приведенном ниже случае вам не нужны никакие атрибуты, когда ключ соответствует имени свойства Id

 public class Parent
{
    public int Id { get; set; }

    public virtual ICollection<Child> Children { get; set; }
}

public class Child
{
    public int Id { get; set; }

    public int ParentId { get; set; }

    public virtual Parent Parent { get; set; }
}
  

миграция для приведенного выше кода генерирует

 migrationBuilder.CreateTable(
    name: "Children",
    columns: table => new
    {
        Id = table.Column<int>(nullable: false)
            .Annotation("SqlServer:Identity", "1, 1"),
        ParentId = table.Column<int>(nullable: false)
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Children", x => x.Id);
        table.ForeignKey(
            name: "FK_Children_Parents_ParentId",
            column: x => x.ParentId,
            principalTable: "Parents",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);
    });
  

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

 public class Parent
{
    public int Id { get; set; }

    public virtual ICollection<Child> Children { get; set; }
}

public class Child
{
    public int Id { get; set; }

    public int MyKey { get; set; }

    [ForeignKey("MyKey")]
    public virtual Parent Parent { get; set; }
}
  

Вы можете использовать fluent метод для изменения имени ограничения

 modelBuilder.Entity<Child>()
    .HasOne(x => x.Parent)
    .WithMany(x => x.Children)
    .HasForeignKey(x => x.MyKey)
    .HasConstraintName("My_Key_name");
  

Комментарии:

1. Спасибо за вашу помощь. По-видимому, я понял это совершенно неправильно… Я перешел на что-то другое и скоро перейду в Entity Framework.