1

我在使用 Entity Framework 时遇到问题,其中我有类似于以下样机的内容:

public class ClassA
{
  public int ClassAID { get; set; }
}

public class ClassB
{
  public int ClassBID { get; set; }
}

public class ClassC
{
  public int ClassAID { get; set; } //Foreign Keys combined as Primary Key
  public int ClassBID { get; set; }

  public virtual ClassA SomeA { get; set; }
  public virtual ClassB SomeB { get; set; }
  public virtual ClassD SomeD { get; set; }
}

public class ClassD
{
  public int ClassAID { get; set; } //Primary Key and also references Class C Primary Key
  public int ClassBID { get; set; }

  public virtual ClassC SomeC { get; set; }
}

ClassD 是我遇到问题的地方,我希望表示 ClassC 上的主键的属性是 ClassD 上的主键,但也是外键引用。(假设上面的属性名与表列名相同)

在底层数据库中,ClassC 和 ClassD 的对应表是一对一的关系,而 ClassA 到 ClassC 和 ClassB 到 ClassC 是一对多的关系。

然而,当涉及到实体框架时,它似乎无法同时处理多个同名属性作为主键和外键,在它生成的底层 SQL 中,我可以看到它正在寻找列 ClassD_ClassAID、ClassD_ClassBID -有没有办法使用模型配置来指定正确的映射?

我努力了:

this.HasKey(c => new { c.ClassAID, c.ClassBID });
this.HasRequired(c => c.ClassC)
.WithRequiredDependent();

我也试过:

this.HasKey(c => new { c.ClassAID, c.ClassBID });
this.HasRequired(c => c.ClassC)
.WithRequiredDependent()
.Map(m => m.MapKey("ClassAID", "ClassBID"));

到目前为止,任何引入映射的尝试都会遇到

'元数据中已存在属性名称 xxx'。

4

1 回答 1

4

我不确定以下是否可以解决您的问题,因为我不明白您提到的异常可能来自哪里:

modelBuilder.Entity<ClassC>()
    .HasKey(c => new { c.ClassAId, c.ClassBId });

modelBuilder.Entity<ClassD>()
    .HasKey(d => new { d.ClassAId, d.ClassBId })
    .HasRequired(d => d.SomeC)
    .WithRequiredDependent(c => c.SomeD);

此处重要的部分是您在 中指定关系另一侧的导航属性WithRequiredDependent。如果您使用无参数重载,EF 将在 and 之间创建第二个关系,ClassC并且ClassD属于SomeD此关系,而不是您正在配置的关系。

如果您没有指定任何进一步的映射ClassAClassBEF 将根据上述映射和约定创建以下三个关系:

  • ClassA -> ClassC(FK = ClassC 中的 ClassAId)
  • ClassB -> ClassC(FK = ClassC 中的 ClassBId)
  • ClassC -> ClassD(FK = ClassAId,ClassD 中的 ClassBId)

所以,ClassD有一个复合主键,它同时是一个复合外键ClassC

于 2011-10-17T17:29:27.690 回答