可变的“标量导航属性”在EF 4.0中:将不可为空的列从单独的数据库表映射到可空的标量实体属性? [英] Nullable "scalar navigation properties" in EF 4.0: Mapping a non-nullable column from a separate database table to a nullable scalar entity property?

查看:195
本文介绍了可变的“标量导航属性”在EF 4.0中:将不可为空的列从单独的数据库表映射到可空的标量实体属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用实体框架版本4.0(或与.NET 4.0兼容的任何其他版本),我想映射此现有的关系数据库模式:

Using Entity Framework version 4.0 (or any other version that is compatible with .NET 4.0), I want to map this existing relational database schema:

逻辑对象模型:

我已经尝试设置如下:(希望德语字幕不会太迷惑。)

which I have tried setting up as follows: (I hope the German captions won't be too disorienting.)

实体框架给我这个错误:

Entity Framework gives me this error:


错误3031:问题在映射片段...:表中的非空值列 FooBs.B FooBs 映射到可空的实体属性。 em>

Error 3031: Problem in mapping fragments …: Non-nullable column FooBs.B in table FooBs is mapped to a nullable entity property.

在逻辑模型中, B 应为可空。但是,在数据库中,它不是,因为它驻留在单独的表中。 (我喜欢避免可空的数据库列。)当 Foos FooBs 被加入(由于1:0..1基数)

In the logical model, B ought to be nullable. However, in the database, it isn't, because it resides in a separate table. (I like to avoid nullable database columns.) It only becomes nullable when Foos and FooBs are joined (due to the 1:0..1 cardinality).

如何修改我的映射,而不改变数据库模式或对象模型?

How can I fix my mapping, without altering either the database schema or the object model?


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

P.S.: I also tried this EF 6.0 code-first mapping:

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 中的所有 Foo B 属性设置为 null

But this doesn't work either: When reading from the database, EF ignores all records for which there is no sub-record in FooBs; when writing to the database, it attempts to insert NULL into FooBs.B for all Foo that have their B property set to null.


推荐答案

应该有一个相当脏的解决方案。这将需要一些代码更改,但会留下您的 Foo 实体与字段 A B

There is a rather "dirty" solution that should work. It would require some code changing but would leave your Foo entity with field A and B.

Foo class:

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

And mapped to database class FooB:

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

在旁注 - 似乎非常奇怪的方式添加基本单个可空列到一个表,因为没有逻辑的方式,其中 FooB 可以有多个不可空列,这不会导致删除整个实体设置列值null。

On side note - it seems like very strange way to add essentially single nullable column to a table, as there is no logical way where FooB could have more than one non-nullable column, that wouldn't result in deleting whole entity on setting columns value to null.

另一个选项是创建一个数据库视图,其行为与您想要的一样,并将其映射到实体。

Another option is creating a database view that would behave like you want and map that to entity.

这篇关于可变的“标量导航属性”在EF 4.0中:将不可为空的列从单独的数据库表映射到可空的标量实体属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆