【问题标题】:Entity Framework 4.1 Fluent mapping Foreign Key and the Foreign object with a string keyEntity Framework 4.1 Fluent 映射外键和带有字符串键的外对象
【发布时间】:2011-09-25 20:31:24
【问题描述】:

我正在从 EDMX 映射迁移到 EF 4.1 DbContext 和 Fluent 映射,并且我想使用 fluent API 映射字符串外键和外来对象。我有一个可选办公室的员工。我想要 Employee 类中的 OfficeId 和 Office 对象(这都是只读的,我不需要能够保存这些对象)。具有 int 键的对象工作正常,但我尝试了几个使用字符串键并获得相同的结果 - OfficeId 字段填充,但 Office 对象返回为空。在 SQL 分析器中检查正在查询数据,但未填充 office 对象。

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字段。

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢,这有助于我进一步改进 - int 键工作正常,但字符串键似乎不起作用。我添加了几个来检查,int键很好,字符串键总是产生一个空对象
      【解决方案3】:

      这不是正确的映射。如果您有 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");
      

      【讨论】:

      • 谢谢,我已按照您的建议更正了映射。对象在一个模式中,遗憾的是我的问题仍然存在 - 如果我将映射更改为 .HasForeignKey 则填充 OfficeId 字段但 Office 对象返回 null (我做了 .Include 它)。如果我删除 OfficeId 字段,.Map 表示法确实有效,然后我可以获取 Office 对象。我发现我必须做 .Map 因为密钥在数据库中被命名为 OfficeId 而不是 Office_Id
      猜你喜欢
      • 2011-12-26
      • 1970-01-01
      • 2017-08-17
      • 1970-01-01
      • 1970-01-01
      • 2021-04-30
      • 1970-01-01
      • 2014-05-26
      • 1970-01-01
      相关资源
      最近更新 更多