Я пытался найти свой путь с EF последние пару дней / недель. В настоящее время я немного застрял в обработке внешних ключей, в этом случае у меня есть таблица с двумя FK для себя (пожалуйста, не задавайте вопросов о моем дизайне БД, так как это просто ситуация, с которой я сталкиваюсь, у меня нет возможности изменить структуру базы данных).
Я сократил свой код до следующего примера, в котором я использую одну таблицу, описанную классом Foo
:
class Foo
{
public int ID { get; set; }
public string Data { get; set; }
public int firstFkID { get; set; }
public int secondFkID { get; set; }
[ForeignKey("firstFkID")]
public virtual Foo firstFk { get; set; }
[ForeignKey("secondFkID")]
public virtual Foo secondFk { get; set; }
}
Мой производный класс от DbContext
:
class EFFKContext : DbContext
{
public EFFKContext(string connectionString) : base(connectionString) { }
public virtual DbSet<Foo> Foo { get; set; }
}
И, конечно же, код, в котором я все это использую:
static void Main(string[] args)
{
SqlConnectionStringBuilder cnStrBuilder = new SqlConnectionStringBuilder()
{
DataSource = "(local)",
InitialCatalog = "EF_FK",
IntegratedSecurity = true
};
EFFKContext context = new EFFKContext(cnStrBuilder.ConnectionString);
Foo foo = context.Foo.Find(3);
Foo fFoo = foo.firstFk;
Foo sFoo = foo.secondFk;
}
Когда я компилирую это, никаких проблем нет, но во время выполнения я получаю следующую ошибку:
Необработанное исключение типа System.InvalidOperationException произошло в> EntityFramework.dll
Дополнительная информация: Невозможно определить главный конец ассоциации> между типами RF_EF_FK.Foo и RF_EF_FK.Foo. Главный конец этой> ассоциации должен быть явно сконфигурирован с использованием либо> текучей связи> API, либо аннотаций данных.
Может ли кто-нибудь объяснить, почему я получаю эту ошибку, что она конкретно означает и указать направление, в котором мне придется изменить свой код, чтобы заставить его вести себя так, как я хочу?
Которая может получить объекты, на которые указывают два FK.
Я пробовал следующее:
Добавление дополнительных свойств навигации, возвращающих коллекцию, хотя это не дает желаемого решения. Кроме того, отношения не являются отношениями «один ко многим», так что это даже не кажется правильным.
Я также пробовал добавить код Fluent API, но опять же это не дало мне нужного решения.
Хотя я пробовал вышеуказанные вещи, вполне возможно, что я что-то там пропустил. Любая помощь приветствуется!
Изменить:
Продолжая поиски решения этой проблемы, я обнаружил, что добавление следующего в мой класс контекста решит проблему FK.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Foo>().HasOptional(f => f.secondFk).WithMany().HasForeignKey(f => f.secondFkID);
modelBuilder.Entity<Foo>().HasOptional(f => f.firstFk).WithMany().HasForeignKey(f => f.firstFkID);
}
Теперь при загрузке объекта из базы данных мне нужно использовать функции Include
, чтобы сразу включить связанные объекты, или использовать следующее, чтобы загрузить его позже:
context.Entry(sFoo).Reference("firstFk").Load();
Тем не менее, все еще не уверен, стоит ли это делать.
2 ответа
В связи с тем, что никаких других ответов, кроме ответа Джениш Рададия, не было, я опубликую свои собственные выводы в качестве ответа.
Продолжая поиски решения этой проблемы, я обнаружил, что добавление следующего в мой класс контекста решит проблему FK.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Foo>().HasOptional(f => f.secondFk).WithMany().HasForeignKey(f => f.secondFkID);
modelBuilder.Entity<Foo>().HasOptional(f => f.firstFk).WithMany().HasForeignKey(f => f.firstFkID);
}
Теперь, при загрузке объекта из базы данных, мне нужно использовать функции Include, чтобы сразу включить связанные объекты, или использовать следующее, чтобы загрузить его позже:
context.Entry(sFoo).Reference("firstFk").Load();
Тем не менее, все еще не уверен, стоит ли это делать.
Возможно, вам потребуется сделать одно поле допускающим значение NULL. Я не очень в этом уверен.
Вместо этого вы можете использовать Fluent api для подготовки отношения модели.
class Foo
{
public int ID { get; set; }
public string Data { get; set; }
public int firstFkID { get; set; }
public int secondFkID { get; set; }
//[ForeignKey("firstFkID")] <- remove this while using fluent api
public virtual Foo firstFk { get; set; }
//[ForeignKey("secondFkID")] <- remove this while using fluent api
public virtual Foo secondFk { get; set; }
}
Попробуй это.
public class FooConfiguration : EntityTypeConfiguration<Foo>
{
public FooConfiguration()
{
this.HasKey(x => x.ID);
this.HasOptional(f => f.firstFk)
.WithOptionalDependent(f => f.secondFk);
}
}
Я также нашел один связанный поток stackoverflow => здесь
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.