使用EF 6,并给出以下课程:

public class A: 
{
    public int Id{ get; set; }

    public string PropA {get; set;}
    public string PorpB {get; set;} 

    public List<B> Bs {get; set;}
}

public class B: 
{
    public int Id {get; set;}
    public string PropB {get; set;}
    public string PorpC {get; set;} 
}

我想创建一个A对多个B的关系,问题是在复合主键中有不同的名称:

A类中的财产PropB对应于B类中的PropB,而A类中的PropA必须对应于B类中的PropC.

我try 使用模型构建器,但找不到将A类的名称映射到B类的位置:

modelBuilder.Entity<A>(a=>
{
    a.HasKey(a => a.Id);
    a.HasMany(a=> a.Bs).WithOne().HasPrincipalKey("PropA", "PropB"); <= Can't find PropA in classB
});

我怎么能做到这一点?

Note:我不能修改数据库,也不能使用ID属性创建关系.

推荐答案

好的!添加一个.HasForeignKey调用(并优先使用连贯配置方法的lambda版本).

modelBuilder.Entity<A>(a =>
{
    a.HasKey(a => a.Id);
    a.HasMany(a => a.Bs).WithOne()
        .HasPrincipalKey(a => new { a.PropA, a.PropB })
        .HasForeignKey(b => new { b.PropC, b.PropB });
});

以及由此产生的表定义:

CREATE TABLE [A] (
  [Id] int NOT NULL IDENTITY,
  [PropA] nvarchar(450) NOT NULL,
  [PropB] nvarchar(450) NOT NULL,
  CONSTRAINT [PK_A] PRIMARY KEY ([Id]),
  CONSTRAINT [AK_A_PropA_PropB] UNIQUE ([PropA], [PropB])
);
CREATE TABLE [B] (
  [Id] int NOT NULL IDENTITY,
  [PropB] nvarchar(450) NOT NULL,
  [PropC] nvarchar(450) NOT NULL,
  CONSTRAINT [PK_B] PRIMARY KEY ([Id]),
  CONSTRAINT [FK_B_A_PropC_PropB] FOREIGN KEY ([PropC], [PropB])
      REFERENCES [A] ([PropA], [PropB]) ON DELETE CASCADE
);

请注意,类A中对PropAPropB的引用会导致EF在这些属性上生成唯一索引,以使标识成功.(或者,当不使用迁移时,它会使EF假定组合是唯一的.)

换句话说,对于EF,这两个属性是alternate key(因此索引中的前缀为AK).这也意味着,正如主键属性一样,您不能使用EF修改这些属性,因此这是一个需要仔细考虑的设计决策.

Csharp相关问答推荐

在实际上是List T的 IESEARCH上多次调用First()是否不好?

C#自定义字典与JSON(de—)serialize

如何使用ConcurentDictionary属性上的属性将自定义System.Text.Json JsonConverter应用于该属性的值?

模型绑定RazorPage表单

如何在不考虑年份的情况下判断日期时间是否在某个日期范围内?

C#XmlSerializer-输出控制新行的多个XML片段

查找表中的模式

UWP应用程序try 将打包的本机.exe文件加载为C#程序集

C#DateTime.ParseExact不使用特定日期

将字节转换为 struct 并返回

当试图限制EF Select 的列时,如何避免重复代码?

如何使用用于VS代码的.NET Maui扩展在我的iOS/Android设备或模拟器上进行调试?

如何避免在.NET中将日志(log)写入相对路径

Postgres ENUM类型在第一次运行时对Dapper不可见

为什么C#/MSBuild会自发地为不同的项目使用不同的输出路径?

Blazor:搜索框在第一次搜索时不搜索

将字符串类型日期输入(yyyy-mm-ddthh:mm:ss)转换为MM/dd/yyyy格式

项目参考和方法签名问题

如何为控制器PUT操作绑定对象数组

将两个JSON文件与覆盖值的主文件合并