Что означает основной конец ассоциации в соотношении 1:1 в структуре Entity
public class Foo
{
public string FooId{get;set;}
public Boo Boo{get;set;}
}
public class Boo
{
public string BooId{get;set;}
public Foo Foo{get;set;}
}
Я пытался сделать это в Entity Framework, когда получил ошибку:
Невозможно определить главный конец связи между типами 'ConsoleApplication5.Boo' и 'ConsoleApplication5.Foo'. Основной конец этой ассоциации должен быть явно сконфигурирован с использованием либо свободно распространяемые API или аннотации данных.
Я видел вопросы о StackOverflow с решением для этой ошибки, но я хочу понять, что означает термин "главный конец".
Ответы
Ответ 1
В отношениях "один к одному" один конец должен быть основным, а второй конец должен быть зависимым. Основной конец - тот, который будет вставлен первым и который может существовать без зависимого. Зависимый конец - тот, который должен быть вставлен после принципала, потому что у него есть внешний ключ для принципала.
В случае сущности фрейма FK в зависимом случае также должен быть PK, поэтому в вашем случае вы должны использовать:
public class Boo
{
[Key, ForeignKey("Foo")]
public string BooId{get;set;}
public Foo Foo{get;set;}
}
Или плавное отображение
modelBuilder.Entity<Foo>()
.HasOptional(f => f.Boo)
.WithRequired(s => s.Foo);
Ответ 2
Вы также можете использовать атрибут аннотации данных [Required]
, чтобы решить эту проблему:
public class Foo
{
public string FooId { get; set; }
public Boo Boo { get; set; }
}
public class Boo
{
public string BooId { get; set; }
[Required]
public Foo Foo {get; set; }
}
Foo
требуется для Boo
.
Ответ 3
Это со ссылкой на @Ladislav Mrnka ответ на использование свободного api для настройки отношения "один к одному".
Если бы ситуация FK of dependent must be it PK
была невозможной.
например:
Foo уже имеет отношения "один ко многим" с Bar.
public class Foo{
public Guid FooId;
public virtual ICollection<> Bars;
}
public class Bar{
//PK
public Guid BarId;
//FK to Foo
public Guid FooId;
public virtual Foo Foo;
}
Теперь нам пришлось добавить еще одну взаимную связь между Foo и Bar
а именно
public class Foo{
public Guid FooId;
pubic Guid PrimaryBarId;// needs to be removed(from entity),as we specify it in fluent api
public virtual Bar PrimaryBar;
public virtual ICollection<> Bars;
}
public class Bar{
public Guid BarId;
public Guid FooId;
public virtual Foo PrimaryBarOfFoo;
public virtual Foo Foo;
}
Вот как указать отношения "один-к-одному", используя беглый api:
modelBuilder.Entity<Bar>()
.HasOptional(p => p.PrimaryBarOfFoo)
.WithOptionalPrincipal(o => o.PrimaryBar)
.Map(x => x.MapKey("PrimaryBarId"));
Обратите внимание, что при добавлении PrimaryBarId
необходимо удалить, поскольку мы укажем его через беглый api.
Также обратите внимание, что имя метода [WithOptionalPrincipal()][1]
является своеобразным ироничным. В этом случае Principal Bar. Описание WithOptionalDependent() в msdn делает его более понятным.