3

使用 Entity Framework 4.0 版(或与 .NET 4.0 兼容的任何其他版本),我想映射这个现有的关系数据库架构:

关系数据库模式

到这个逻辑对象模型:

逻辑对象模型

我尝试设置如下:(我希望德语字幕不会太迷失方向。)

Entity Framework 的 <code>Foo</code> 实体的映射详细信息及其 <code>B</code> 属性的设置

实体框架给了我这个错误:

FooBs.B错误 3031:映射片段时出现问题……:表中的不可为空列FooBs映射到可空实体属性。

在逻辑模型中,B应该可以为空。但是,在数据库中,它不是,因为它驻留在单独的表中。(我喜欢避免可以为空的数据库列。)它只有在FoosFooBs被连接时才可以为空(由于 1:0..1 基数)。

如何在不更改数据库架构或对象模型的情况下修复我的映射?


PS:我也试过这个 EF 6.0 代码优先映射:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Foo>()
    .HasKey(f => f.Id)
    .Property(f => f.Id).HasColumnName("FooId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
    modelBuilder.Entity<Foo>().Map(f => {
        f.Property(_ => _.A);
        f.ToTable("Foos");
    }).Map(f => {
        f.Property(_ => _.B);
        f.ToTable("FooBs");
    });
}

但这也不起作用:从数据库中读取时,EF 会忽略 ; 中没有子记录的所有记录FooBs。写入数据库时​​,它会尝试将所有属性设置NULL为.FooBs.BFooBnull

4

1 回答 1

3

有一个相当“肮脏”的解决方案应该可以工作。这将需要更改一些代码,但会为您的Foo实体留下字段AB.

Foo班级:

class Foo {
   [Key]
   public int FooId { get; set; }
   public int A { get; set; }
   [NotMapped]
   public int? B {
      get {
         return FooB == null ? null : FooB.B;
      }
      set {
         if(value == null) {
            FooB = null;
         } else {
            if(FooB == null)
               FooB = new FooB();
            FooB.B = (int)value;
         }
   public virtual FooB FooB{ get; set; }
}

并映射到数据库类FooB

 class FooB {
    [Key, ForeignKey("FooId")]
    public int FooId { get; set; }
    public int B { get; set; }
 }

附带说明 - 将基本上单个可为空的列添加到表中似乎是一种非常奇怪的方式,因为没有逻辑方式FooB可以有多个不可为空的列,这不会导致在设置列值时删除整个实体为空。

另一种选择是创建一个行为像您想要的数据库视图并将其映射到实体。

于 2014-04-20T17:14:47.593 回答