实体框架6流畅的API,如何用复合键映射导航键到视图
本文关键字:复合 何用 映射 导航 视图 框架 API 实体 | 更新日期: 2023-09-27 17:51:00
我有3个表,其中Property有一个外键到Dependent, Dependent有一个外键到Main,导致每个表的一对多关系。然而,我只对依赖及其属性记录中的最新记录感兴趣,因此我创建了一个视图v_Dependent,它返回由MainId分组的最新依赖记录。这将启用Main和Dependant之间的一对一关系,这就是我所追求的,与下面的代码一起工作。
我在加载主对象时急于加载所有,但是在我切换到视图后,我可能不再急于加载依赖的属性集合中的记录。这样做的原因是为了将视图映射到一对一的关系,我必须将MainId添加到Dependent的复合键中。现在,Property的外键也必须包含MainId,以便能够加载集合,但是我在数据库表中没有MainId,我也不想这样做。
我的问题是,我是否必须为属性创建一个视图,以包括MainId并将其添加到实体复合外键,或者还有什么我可以做的映射使用流畅的API?我目前使用的另一个选项是显式地在我的存储库中加载属性集合,但是我希望流畅的API可以为我处理这个问题。注释出的行是为整个图工作的配置,而我把依赖作为Main上的集合。我使用只读的实体,所以不必担心存储。
public class Main
{
public int MainId { get; set; }
public Dependent Dependent { get; set; }
}
public class Dependent
{
public int DependentId { get; set; }
public int MainId { get; set; }
public Main Main { get; set; }
public ICollection<Property> Properties { get; set; }
}
public class Property
{
public int PropertyId { get; set; }
public int DependentId { get; set; }
public Dependent Dependent { get; set; }
}
public class SomeContext : DbContext
{
public DbSet<Main> Mains { get; set; }
public DbSet<Dependent> Dependents { get; set; }
public DbSet<Property> Properties { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Main>().ToTable("Main").HasKey(m => m.MainId);
//modelBuilder.Entity<Dependent>().ToTable("Dependent").HasKey(d => d.DependentId).HasRequired(d => d.Main).WithMany(m => m.Dependents).HasForeignKey(d => d.MainId);
modelBuilder.Entity<Dependent>().ToTable("v_Dependent").HasKey(d => new {d.DependentId, d.MainId}).HasRequired(d => d.Main).WithOptional(m => m.Dependent);
modelBuilder.Entity<Property>().ToTable("Property").HasKey(p => p.PropertyId).HasRequired(p => p.Dependent).WithMany(d => d.Properties).HasForeignKey(p => p.DependentId);
base.OnModelCreating(modelBuilder);
}
}
经过大量的挖掘,我发现潜在的问题是实体框架无法使用外键而不是主键来映射1到0或1关系。见https://entityframework.codeplex.com/workitem/299
因此,我不得不在更改Dependent的主键(它目前是一个视图,因此我可以创建一个具有所有此类限制的索引视图,但我有一个子查询我无法摆脱)或单独加载属性之间做出选择。我选择了后者,并更改了应用程序,使其不再具有导航属性,并在需要时加载属性。