【问题标题】:Foreign key with entity framework code first approach具有实体框架代码优先方法的外键
【发布时间】:2014-04-01 03:10:15
【问题描述】:

我已经阅读了关于 stackoverflow 上的 EF 外键问题的许多问题及其建议的解决方案。但没有一个适合我的情况。

我有一个父类 XSection

public class XSection
{
  public int ObjectId {get; set;}
  public OverBank LeftOverBank {get; set;}
  public OverBank RightOverBank {get; set;}
}

overbanks 是父 Xsection 类的子实体(只有一个不在列表中)。 OverBanks 类看起来像

public class OverBank
{
  public int ObjectId {get; set;}
  public int ParentId (get; set;}

  public double Station {get; set;}
  // some other basic properties 
}

为上述类生成的 DDL 是:

横截面表

CREATE TABLE CrossSection ( 
  ObjectID INTEGER NOT NULL,
  LeftOverbank_ObjectID INTEGER NULL,
  RightOverbank_ObjectID INTEGER NULL,
  PRIMARY KEY (ObjectID),
  FOREIGN KEY (LeftOverbank_ObjectID) REFERENCES Overbank (ObjectID) ON DELETE CASCADE,
  FOREIGN KEY (RightOverbank_ObjectID) REFERENCES Overbank (ObjectID) ON DELETE CASCADE,
);

CREATE INDEX IX_FK_CrossSection_LeftOverbank ON CrossSection (LeftOverbank_ObjectID);

CREATE INDEX IX_FK_CrossSection_RightOverbank ON CrossSection (RightOverbank_ObjectID);

OverBank 表

CREATE TABLE Overbank ( 
  ObjectID INTEGER NOT NULL,
  Station real NULL,
  DisplayLabel text NULL,
  Description text NULL,
  Name text NULL,
  PRIMARY KEY (ObjectID),

);

为了启用级联删除,我在 OnModelCreating 事件中写了以下内容:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{

    modelBuilder.Entity <CrossSection>()
              .ToTable("CrossSection");
     modelBuilder.Entity <Overbank>()
              .ToTable("Overbank");

    modelBuilder.Entity<CrossSection>().HasOptional(xs => xs.LeftOverbank).WithMany().WillCascadeOnDelete(true);
    modelBuilder.Entity<CrossSection>().HasOptional(xs => xs.RightOverbank).WithMany().WillCascadeOnDelete(true);

    base.OnModelCreating(modelBuilder);
}

我们可以看到外键约束被颠倒了。此外,当我删除与过岸相关的横截面时,不会被删除,而当我删除与过岸相关的横截面时,会被删除。而我们需要的正好与我们现在所拥有的相反。有没有很傻的东西。

【问题讨论】:

  • 这就是你写的所有映射配置吗?还是还有更多?
  • 我已经编辑了完整的 OnModelCreating 事件。

标签: c# entity-framework sqlite ef-code-first cascade


【解决方案1】:

这些 Overbank 属性中的每一个实际上都是 0..1:1 的关系。那是“零或一对一”。试试WithRequiredPrincipal(),而不是WithMany()

【讨论】:

  • 哦,我明白了,我将其更改为 modelBuilder.Entity().HasOptional(xs => xs.LeftOverbank).WithOptionalPrincipal().WillCascadeOnDelete(true);。现在关系正在正确建立,但级联删除未设置为 true。
  • 可能是因为此模型不能真正符合实体框架约定。 EF 要求 1:1 和 0..1:1 关系中的表具有相同的主键,主表生成标识,从属表没有标识列。但是这种约定会使双 0..1:1 的关系变得不可能。让我回过头来问一个更广泛的问题。如果 Overbank 只是一个双精度数(除非您知道它需要是浮点数,否则它可能应该是一个小数)并且关系是 0..1:1 与级联删除,那么为什么要将它们放在单独的表中呢?
  • 为了保持示例简单,我还没有提到其他属性。此外,当我使用 dbEditor 手动更新 CASCADE 删除选项时,一切正常。
猜你喜欢
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 2015-02-24
  • 2021-01-05
相关资源
最近更新 更多