Аннотированный класс с некоторым описанием:
public class MyClass
{
// [Key] - Don't actually need this attribute
// EF Code First has a number of conventions.
// Columns called "Id" are assumed to be the Key.
public Guid Id {get; set; }
// This reference creates an 'Independent Association'. The Database
// foreign key is created by convention and hidden away in the code.
[Required]
public virtual OtherClass OtherClass { get; set; }
// This setup explicitly declares the foreign key property.
// Again, by convention, EF assumes that "FooId" will be the key for
// a reference to object "Foo"
// This will still be required and a cascade-on-delete property
// like above - an int? would make the association optional.
public int OtherClass2Id { get; set; }
// Leave the navigation property as this - no [Required]
public virtual OtherClass2 { get; set; }
}
Так что лучше? Независимые ассоциации или объявление внешнего ключа?
Независимые ассоциации ближе соответствуют объектному программированию.С ООП один объект не особо заботится об идентификаторе члена.ORM пытается скрыть эти отношения с разной степенью успеха.
Объявление внешнего ключа ставит проблемы базы данных в вашу модель, но есть сценарии, в которых это значительно облегчает работу с EF.
Пример - при обновлении объекта требуемой независимой ассоциацией EF захочет иметь весь граф объектов на месте.
public class MyClass
{
public int Id {get; set; }
public string Name { get; set; }
[Required] // Note the required. An optional won't have issues below.
public virtual OtherClass OtherClass { get; set; }
}
var c = db.MyClasses.Find(1);
c.Name = "Bruce Wayne";
// Validation error on c.OtherClass.
// EF expects required associations to be loaded.
db.SaveChanges();
Если все, что вы хотите сделать, это обновить имя, вам придется либотакже извлеките OtherClass из базы данных, поскольку он требуется для проверки сущности или присоедините заглушенный объект (при условии, что вы знаете идентификатор) .Если вы явно объявите внешний ключ, вы не столкнетесь с этим сценарием.
Теперь с внешними ключами вы столкнетесь с другой проблемой:
public class MyClass
{
public Guid Id {get; set; }
public string Name { get; set; }
public int OtherClassId { get; set }
public virtual OtherClass OtherClass { get; set; }
}
var c = db.MyClasses.Find(1);
// Stepping through dubugger, here, c.OtherClassId = old id
c.OtherClass = somethingElse;
// c.OtherClassId = old id - Object and id not synced!
db.SaveChanges();
// c.OtherClassId = new id, association persists correctly though.
В итоге -
Независимые ассоциации
- Хорошо: лучше сопоставлять ООП и POCO
- Плохо: часто требуется полный граф объектов, даже если вы обновляете только одинили два свойства.Больше головных болей EF.
Иностранные ключи
- Хорошо: иногда легче работать - меньше головных болей EF.
- Плохо:Может быть не синхронизирован с их объектом
- Плохо: проблемы с базой данных в вашем POCO