我试图使用Fluent API和.Include()获取一些嵌套的数据。我正在使用的数据库没有正常化,我无法控制它。实体框架(代码优先)一对多 - 生成额外的字段,而不是使用映射的键
“父”表是TASK,“子”表是STOCK_MOVEMENT,其中“许多股票移动到一个任务”关系。
该映射应该来自TASK,其复合关键字{“TSK_SITE”,“TSK_TYPE”}到STOCK_MOVEMENT上,复合关键字{“MOV_SITE”,“MOV_TYPE”,“MOV_MOVE”}。
article here似乎最适合我的任务,特别是“配置复合外键”部分。不幸的是,我似乎没有得到我的intellisense为“HasForeignKey”系列提示的预期字段,所以我不得不尝试别的东西......(想法欢迎!)
我试过的是这样的:
this.HasRequired(sm => sm.TestTask)
.WithMany(t => t.Movements)
.Map(m => m.MapKey("MOV_SITE", "MOV_TYPE"));
试图“HasRequired”和“HasOptional”...但是,最终由EF生成的SQL包含额外的字段,而不是根据我指定的外键映射。
任何人都可以解释我应该如何改变我的映射以获得正确的SQL吗? 指导性问题也非常受欢迎。
我附上以下所有相关代码...
非常感谢!
维多利亚
public class TestTask : IMyObject
{
public TestTask()
{
this.KeyFields = new string[] { "Site", "TaskType" };
this.Movements = new HashSet<TestMovement>();
}
public string Site { get; set; }
public string TaskType { get; set; }
public string Key { get; set; }
public virtual HashSet<TestMovement> Movements { get; set; }
//... more code
}
internal partial class TestTask_Mapping : EntityTypeConfiguration<TestTask>
{
public TestTask_Mapping()
{
this.HasKey(t => new { t.Site, t.TaskType });
this.ToTable("TASK");
this.Property(t => t.Site)
.HasColumnName("TSK_SITE")
.IsRequired();
this.Property(t => t.TaskType)
.HasColumnName("TSK_TYPE")
.IsRequired();
this.Property(t => t.Key)
.HasColumnName("TSK_REF");
}
}
public class TestMovement : IMyObject
{
public TestMovement()
{
this.KeyFields = new string[] { "Site", "MoveType" };
}
public string Site { get; set; }
public string MoveType { get; set; }
public string Key { get; set; }
public virtual TestTask TestTask { get; set; }
// ... more code
}
public class TestStockMovement_Mapping : EntityTypeConfiguration<TestMovement>
{
public TestStockMovement_Mapping()
{
this.HasKey(t => new { t.Site, t.MoveType });
this.HasRequired(sm => sm.TestTask)
.WithMany(t => t.Movements)
.Map(m => m.MapKey("MOV_SITE", "MOV_TYPE"));
this.Property(t => t.Site)
.IsRequired();
this.Property(t => t.MoveType)
.IsRequired();
this.ToTable("STOCK_MOVEMENT");
//this.Property(t => t.Site).HasColumnName("MOV_SITE");
//this.Property(t => t.MoveType).HasColumnName("MOV_TYPE");
this.Property(t => t.Key).HasColumnName("MOV_MOVE");
}
}
// In DbContext...
public DbSet<TestTask> TestTasks { get; set; }
public DbSet<TestMovement> TestStockMovements { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new TestTask_Mapping());
modelBuilder.Configurations.Add(new TestStockMovement_Mapping());
}
// In the appropriate method in the repository ...
IQueryable<TestTask> testTasks = context.TestTasks.Include(t => t.Movements);
// Where testTasks results in the SQL with incorrect foreign key field references
// (please see the picture that tells a thousand words below)...
为了阐明在数据库字段和所涉及的表:我只提及用作键的简化问题列:
1)“TASK “表包含构成其组合键(+更多列)的列”TSK_SITE“和”TSK_TYPE“。
2)“STOCK_MOVEMENT”表包含列“MOV_SITE”,“MOVE_TYPE”和“MOV_MOVE”,它们是组合键的一部分(+更多列)。我没有在我的映射中使用“MOV_MOVE”,因为父TASK表中没有等效列。
我期望为每个TASK记录检索一个或多个STOCK_MOVEMENT记录。
如果'{“MOV_SITE”,“MOV_TYPE”}'是'STOCK_MOVEMENT'表中的主键,那么TASK'表的外键是什么?如果关系是一对多的,它不能再是“{”MOV_SITE“,”MOV_TYPE“}(如你的映射所说)。如果PK和FK是相同的,这只能是一对一的关系。 – Slauma 2014-09-30 18:19:29
非常感谢回复我的问题,Slauma!我在原始文章中添加了一个编辑,阐明了STOCK_MOVEMENT表中有一列是该表的组合键的一部分,但是我没有将其添加到映射关系中。在父TASK表中没有与该列等效的内容,因此没有任何内容可映射到该列。我该如何(我应该)在我的代码中创建一对多的帐户列... – Victoria 2014-09-30 19:34:04