【发布时间】:2021-08-14 04:40:07
【问题描述】:
在实体框架中,如何将一个虚拟集合链接到另一个使用复合键的表?这是两个示例表:
public abstract class Table1
{
public Guid EventId { get; set; }
public string EventName { get; set; }
public virtual ICollection<Table2> Table2 { get; private set; }
}
和
public abstract class Table2
{
public Guid EventId { get; set; }
public string DetailKey { get; set; }
public string DetailValue { get; set; }
public virtual Table1 Table1 { get; set; }
}
意思是在Table1中添加一个事件,然后使用一对多的关系,向Table2添加N行。在表1中,GuidEventId是PK,在表2中,PK是EventId + DetailKey的合成,这意味着表2中可能有N行与表1中对应的EventId相关。 Table2 对 Table1 的 EventId 也有一个 FK 为 EventId。
Table1 的地图文件如下所示(部分):
public override void ConfigureImp(EntityTypeBuilder<Table1> builder)
{
base.ConfigureImp(builder);
// Relationships
builder.HasMany(t => t.Table2)
.WithOne(t => t.Table1)
.HasForeignKey(x => new { x.EventId, x.DetailKey });
}
Table2 的地图文件如下所示(部分):
public override void ConfigureImp(EntityTypeBuilder<Table2> builder)
{
base.ConfigureImp(builder);
// Relationships
builder.HasOne(t => t.Table1)
.WithMany(t => t.Table2)
.HasForeignKey(x => x.EventId)
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
}
让我们添加一些数据,比如向 Table1 添加 1 行 EventId FOO,向 Table2 添加 5 行,其中 Table2 中的每一行具有相同的 EventId(以满足 FK)但唯一的 DetailKey(以满足复合键)。完成此操作后,我运行如下查询:
Table1 target = db.Table1
.Include(x => x.Table2)
.SingleOrDefault(x => x.EventId.Equals("FOO"));
执行此操作并检查target 的内容(例如,作为断点)我希望看到来自Table1 的详细信息,以及来自Table2 的所有5 行,因为.Include。但是,我实际上得到的只是 Table2 中的一行,无论哪一行在表中先出现(这意味着它可以随着 EventId 的其他行添加到 Table2 中而改变。
有什么想法为什么我没有使用上面为target 显示的查询从 Table2 中获取所有相应的行?谢谢。
【问题讨论】:
-
您用来插入数据库的方法在哪里? “...获取只是 Table2 中的一行”你的意思是从数据库对吗?
-
是的,来自数据库。就示例而言,数据可以手动到达数据库。所以在
target示例中,最后db是包含Table1和Table2模型的数据库上下文。
标签: c# sql-server entity-framework entity-framework-core