实体与实体框架之间的复杂关系 [英] Complex relationship between entities with Entity Framework

查看:77
本文介绍了实体与实体框架之间的复杂关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许是重复的,但我找不到这样的话题。

Maybe it is a duplicate but I couldn't find any topic like this.

我正在使用Entity Framework,并且数据库中有两个表:

I am using Entity Framework and have two tables in my database:

public class A
{
    public virtual B B1 { get; set; }
    public virtual B B2 { get; set; }
}

public class B
{
    public virtual A A1 { get; set; }
}

B1和A1或B2和A1之间没有关系。就像3种单向关系。您如何在Entity Framework中做到这一点?

And there is no relation between B1 and A1 or B2 and A1. It is like 3 one way relation. How can you do that in Entity Framework?

我遇到此错误:


在保存不为其关系公开外键属性的实体时发生错误

An error occurred while saving entities that do not expose foreign key properties for their relationships

有人知道如何处理吗?

预先感谢

推荐答案

因为您没有指出您正在使用的EF版本让我们看一下两个最新版本,即EF 6.2.0和EF-core 2.2.4。

Since you don't indicate in which EF version you're using let's look at the two current versions, EF 6.2.0 and EF-core 2.2.4.

有了EF6,这很容易。映射...

With EF6, it's easy. The mapping...

modelBuilder.Entity<A>().HasRequired(a => a.B1).WithMany();
modelBuilder.Entity<A>().HasRequired(a => a.B2).WithMany().WillCascadeOnDelete(false);
modelBuilder.Entity<B>().HasRequired(b => b.A1).WithMany().WillCascadeOnDelete(false);

...产生以下数据库模型(忽略索引):

...produces the following database model (ignoring indexes):

CREATE TABLE [dbo].[A] (
    [ID] [int] NOT NULL IDENTITY,
    [B1_ID] [int] NOT NULL,
    [B2_ID] [int] NOT NULL,
    CONSTRAINT [PK_dbo.A] PRIMARY KEY ([ID])
)
CREATE TABLE [dbo].[B] (
    [ID] [int] NOT NULL IDENTITY,
    [A1_ID] [int] NOT NULL,
    CONSTRAINT [PK_dbo.B] PRIMARY KEY ([ID])
)

....其中 _ 是外键,其中之一可以级联删除。

....in which the fields with _ are foreign keys, one of which can have cascaded delete.

有了ef-core,它不是那么简单,甚至是越野车,似乎。第一个冲动是EF6等效项:

With ef-core, it's not so straightforward, even buggy, seemingly. The first impulse is the EF6 equivalent:

modelBuilder.Entity<A>().HasOne(a => a.B1).WithMany();
modelBuilder.Entity<A>().HasOne(a => a.B2).WithMany();
modelBuilder.Entity<B>().HasOne(b => b.A1).WithMany();

但是生成的模型不是人们期望的:

But the generated model isn't what one would expect:

  CREATE TABLE [B] (
      [ID] int NOT NULL IDENTITY,
      [A1ID] int NULL,
      CONSTRAINT [PK_B] PRIMARY KEY ([ID])
  );
  CREATE TABLE [A] (
      [ID] int NOT NULL,
      [B1ID] int NULL,
      CONSTRAINT [PK_A] PRIMARY KEY ([ID]),
      CONSTRAINT [FK_A_B_B1ID] FOREIGN KEY ([B1ID]) REFERENCES [B] ([ID]) ON DELETE NO ACTION,
      CONSTRAINT [FK_A_B_ID] FOREIGN KEY ([ID]) REFERENCES [B] ([ID]) ON DELETE CASCADE
  );
  ALTER TABLE [B] ADD CONSTRAINT [FK_B_A_A1ID] FOREIGN KEY ([A1ID]) REFERENCES [A] ([ID]) ON DELETE NO ACTION;

AB 关联之一被解释为1:1我认为这是一个错误。 WithMany 指令不应留下任何解释的空间。两个看似相同的映射会产生完全不同的数据库关系。

One of the A-B associations is interpreted as 1:1. In my opinion that's a bug. The WithMany instruction shouldn't leave any room for interpretation. Two seemingly identical mappings produce quite different database relationships. That can't be right.

这就是说,通过命名FK列很容易(但不是必须的)使EF处于正确的轨道上:

That said, it's easy (but shouldn't be necessary) to get EF on the right track by naming the FK columns:

modelBuilder.Entity<A>().HasOne(a => a.B1).WithMany().HasForeignKey("B1_ID")
    .IsRequired();
modelBuilder.Entity<A>().HasOne(a => a.B2).WithMany().HasForeignKey("B2_ID")
    .IsRequired().OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<B>().HasOne(b => b.A1).WithMany().HasForeignKey("A1_ID")
    .IsRequired().OnDelete(DeleteBehavior.Restrict);

产生(忽略索引):

  CREATE TABLE [B] (
      [ID] int NOT NULL IDENTITY,
      [A1_ID] int NOT NULL,
      CONSTRAINT [PK_B] PRIMARY KEY ([ID])
  );
  CREATE TABLE [A] (
      [ID] int NOT NULL IDENTITY,
      [B1_ID] int NOT NULL,
      [B2_ID] int NOT NULL,
      CONSTRAINT [PK_A] PRIMARY KEY ([ID]),
      CONSTRAINT [FK_A_B_B1_ID] FOREIGN KEY ([B1_ID]) REFERENCES [B] ([ID]) ON DELETE CASCADE,
      CONSTRAINT [FK_A_B_B2_ID] FOREIGN KEY ([B2_ID]) REFERENCES [B] ([ID]) ON DELETE NO ACTION
  );
  ALTER TABLE [B] ADD CONSTRAINT [FK_B_A_A1_ID] FOREIGN KEY ([A1_ID]) REFERENCES [A] ([ID]) ON DELETE NO ACTION;

请注意,必须显式设置必需的外键字段(如果有)。好吧,这只是实现细节。

Note that the foreign key fields must be set required explicitly (if they are). Well, that's just an implementation detail.

这篇关于实体与实体框架之间的复杂关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆