实体框架4.1使用字符串键Fluent映射外键和外部对象

时间:2011-09-25 20:31:24

标签: entity-framework-4.1 foreign-key-relationship fluent

我正在从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字段。

3 个答案:

答案 0 :(得分:1)

好吧,我发现了这个问题 - 这是一个数据问题 - 主键字符串值是空格填充的,外键值不是(!)。虽然SQL正确地连接表(忽略填充)并获取正确的数据,但似乎EF不会将它关联回正确的对象,因为.NET比SQL关于尾随空白更麻烦。

答案 1 :(得分:0)

您的自定义映射只是因为您已经引入了字符串类型的OfficeId属性而发生冲突。如果从Employee定义中删除OfficeId属性,或者将其更改为int类型,请查看会发生什么。

答案 2 :(得分:0)

这是不正确的映射。如果您有FK属性,则无法使用MapMapKey。这适用于您没有该属性的情况。试试这个:

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");