我正在从EDMX映射转移到EF 4.1 DbContext和Fluent映射,我想使用流畅的API映射字符串外键和外来对象。我有一个有可选办公室的员工。我想在Employee类中使用OfficeId和Office对象(这都是只读的,我不需要能够保存这些对象)。使用int键的对象工作正常,但我尝试了几个字符串键并获得相同的结果 - OfficeId字段填充,但Office对象返回null。在SQL分析器中查询数据正在查询,但办公室对象没有被填充。
public partial class Employee
{
public int Id { get; set; }
// snip irrelevant properties
public Office Office { get; set; } // this is (incorrectly) always null
public string OfficeId { get; set; }
public WorkGroup WorkGroup { get; set; } // this one with the int key is fine
public int? WorkGroupId { get; set; }
// snip more properties
}
public partial class Office
{
public string Id { get; set; }
public string Description { get; set; }
}
public partial class WorkGroup
{
public int Id { get; set; }
public string Code { get; set; }
}
在下面的Ladislav反馈之后,我在OnModelCreating
中将其映射为这样modelBuilder.Entity<Employee>().HasKey(d => d.Id).ToTable("Employee", "ExpertQuery");
modelBuilder.Entity<Office>().HasKey(d => d.Id).ToTable("Office", "ExpertQuery");
modelBuilder.Entity<WorkGroup>().HasKey(d => d.Id).ToTable("WorkGroup", "ExpertQuery");
modelBuilder.Entity<Employee>()
.HasOptional(a => a.Office)
.WithMany()
.Map(x => x.MapKey("OfficeId")); // this one does not work
modelBuilder.Entity<Employee>()
.HasOptional(e => e.WorkGroup)
.WithMany()
.HasForeignKey(e => e.WorkGroupId); // this one works fine
我认为我缺少一些关于字符串键的微妙之处?我查询如下:
var employees = expertEntities.Employees.Include("Office").Include("WorkGroup").Take(10).ToList();
如果我从Employee中省略OfficeId字段,并设置如下映射:
modelBuilder.Entity<Employee>()
.HasOptional(e => e.BusinessEntity)
.WithMany()
.Map(x => x.MapKey("OfficeId"));
然后填充office对象,但我需要Employee对象中的OfficeId字段。
答案 0 :(得分:1)
好吧,我发现了这个问题 - 这是一个数据问题 - 主键字符串值是空格填充的,外键值不是(!)。虽然SQL正确地连接表(忽略填充)并获取正确的数据,但似乎EF不会将它关联回正确的对象,因为.NET比SQL关于尾随空白更麻烦。
答案 1 :(得分:0)
您的自定义映射只是因为您已经引入了字符串类型的OfficeId属性而发生冲突。如果从Employee定义中删除OfficeId属性,或者将其更改为int类型,请查看会发生什么。
答案 2 :(得分:0)
这是不正确的映射。如果您有FK属性,则无法使用Map
和MapKey
。这适用于您没有该属性的情况。试试这个:
modelBuilder.Entity<Employee>()
.HasOptional(a => a.Office)
.WithMany()
.HasForeignKey(a => a.OfficeId);
将映射实体映射到表的第一部分也很可能不正确。 Map
用于继承和实体拆分方案。您正在寻找ToTable
:
modelBuilder.Entity<Employee>().HasKey(d => d.Id).ToTable("ExpertQuery.Employee");
此外,如果您的ExpertQuery
是数据库架构而不是表名的一部分,它应该如下所示:
modelBuilder.Entity<Employee>().HasKey(d => d.Id).ToTable("Employee", "ExpertQuery");