【问题标题】:EntityFramework foreign key as primary key with fluent APIEntityFramework 外键作为主键,具有流畅的 API
【发布时间】:2016-02-03 06:45:19
【问题描述】:

我正在尝试在两个实体之间创建 required:optional 关系,其中 required 实体向可选实体公开导航属性,并且可选实体包含外键,用作其主键。这是我的两个实体的样子:

class OptionalEntity
{
  public string RequiredEntityID { get; set; }
}

class RequiredEntity
{
  public string ID { get; set; }
  public OptionalEntity Optional { get; set; }
}

而我喜欢在 fluent API 中配置它们的方式如下:

// Inside OptionalEntityConfiguration class
public OptionalEntityConfiguration()
{
  HasKey(r => r.RequiredEntityID);
}

// Inside RequiredEntityConfiguration class
public RequiredEntityConfiguration()
{
  HasKey(r => r.ID);
  HasOptional(r => r.Optional)
    .WithRequired();

  //  How can I configure this relationship to use
  //    the RequiredEntityID property as the foreign key?

  HasOptional(r => r.Optional)
    .WithRequired(o => o.RequiredEntityID);
  //  This is invalid because it requires a navigation property, not an ID

  HasOptional(r => r.Optional)
    .WithRequired()
    .HasForeignKey(o => o.RequiredEntityID);
  //  The HasForeignKey method isn't available here
}

首先这是可能的,如果可能的话,使用 fluent API 配置这种关系的正确方法是什么?

【问题讨论】:

  • HasOptional(r => r.Optional).WithRequired(); 就足够了。 EF 知道 OptionalEntityRequiredEntityID 作为 PK 并且其实现 1-0..1 的标准方法是将其设为 PK/FK。

标签: c# entity-framework


【解决方案1】:

我认为您要做的是使用可选实体表上所需实体上使用的相同密钥,以便它们共享相同的密钥。

如果是这样的话,我认为你是在正确的轨道上。您的实体类看起来不错。您可以像这样映射它们:

public OptionalEntityConfiguration()
{
   HasKey(r => r.RequiredEntityID);
   Property(r => r.RequiredEntityID)
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}

public RequiredEntityConfiguration()
{
   HasKey(r => r.ID);
   HasOptional(r => r.Optional);
}

但是,这意味着每个 RequiredEntity 只能有 0 或 1 个 OptionalEntity

【讨论】:

  • 这正是我正在寻找的行为;每个RequiredEntity 有0 或1 个OptionalEntity。你能解释一下HasDatabaseGeneratedOption 方法的作用吗?
  • @AlfieWoodland,HasDatabaseGeneratedOption 是用于指示您希望如何设置属性值(在本例中为 RequiredEntityID)的方法。将其设置为None 表示您不希望数据库为您生成它,您将自己分配它。您想要这样做是因为,此列的任何值都应该来自 RequiredEntity 中父记录的 ID
【解决方案2】:

试试这个:

modelBuilder.Entity<RequiredEntity>()
            .HasOptional(o => o.Optional)
            .WithMany()
            .Map(m => m.MapKey("RequiredEntityID"));

【讨论】:

  • RequiredEntityID 属性在可选实体上公开。像这样配置所需的实体会导致以下验证错误:Each property name in a type must be unique. Property name 'RequiredEntityID' is already defined.
猜你喜欢
  • 1970-01-01
  • 2012-09-05
  • 1970-01-01
  • 1970-01-01
  • 2014-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多