使用Entity Framework 4.0版(或与.NET 4.0兼容的任何其他版本),我想映射现有的关系数据库模式:
到这个逻辑对象模型:
我尝试设置如下:(我希望德语字幕不会太迷惑。)
实体框架给了我这个错误:
错误3031:映射片段时出现问题...:表
FooBs.B
中的非可空列FooBs
被映射到可以为空的实体属性。
在逻辑模型中,B
应该可以为空。但是,在数据库中,它不是,因为它驻留在单独的表中。 (我喜欢避免可以为空的数据库列。)只有在Foos
和FooBs
加入时才会变为可为空(由于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
中,将Foo
属性设置为B
的所有null
。
答案 0 :(得分:3)
有一个相当&#34;脏&#34;解决方案应该工作。这需要更改一些代码,但会使Foo
实体保留字段A
和B
。
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
没有逻辑方式可以有多个不可为空的列,这样就不会出现这种情况。 t导致在将列值设置为null时删除整个实体。
另一种选择是创建一个行为与您想要的一样的数据库视图,并将其映射到实体。