#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.