【问题标题】:Nullable "scalar navigation properties" in EF 4.0: Mapping a non-nullable column from a separate database table to a nullable scalar entity property?EF 4.0 中的可空“标量导航属性”:将不可空列从单独的数据库表映射到可空标量实体属性?
【发布时间】:2014-04-17 15:50:49
【问题描述】:

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

到这个逻辑对象模型:

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

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

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

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

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


P.S.:我也试过这个 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.B 中,以将所有 FooB 属性设置为 null

【问题讨论】:

标签: entity-framework .net-4.0 nullable non-nullable


【解决方案1】:

应该有一个相当“肮脏”的解决方案。这将需要更改一些代码,但会使您的 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 可以有多个不可为空的列,这不会导致删除将列值设置为 null 的整个实体。

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

【讨论】:

  • 感谢您的回答。你说,“有一个……应该可行的解决方案。”据您所知,这只是一个解决方案,还是很可能是唯一的解决方案?
  • 总的来说,这似乎是一个非常奇怪的用例——可能还有其他解决方案,但我想不出另一种解决方案。
  • 谢谢。并不奇怪:据我了解,这只是一个超出 3NF 的数据库规范化案例。我希望 ORM 能够处理这个问题。由于您的解决方案应该有效(尤其是partial class 的某种组合)并且是我得到的唯一回复,我会接受您的回答。非常感谢您的建议!
猜你喜欢
  • 2012-04-22
  • 2021-04-17
  • 2023-02-11
  • 1970-01-01
  • 1970-01-01
  • 2011-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多