使用实体框架版本 4.0(或与 .NET 4.0 兼容的任何其他版本),我想映射此现有关系数据库架构:
对于这个逻辑对象模型:
我尝试设置如下:(我希望德语字幕不会太让人迷失方向。)
实体框架给了我这个错误:
错误 3031:映射片段时出现问题……:不可为 null 的列FooBs.B
在表中FooBs
映射到可为空的实体属性。
在逻辑模型中,B
应该可以为空。然而,在数据库中,它不是,因为它驻留在一个单独的表中。 (我喜欢避免可为空的数据库列。)只有在以下情况下它才变为可为空:Foos
and 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
into FooBs.B
对全部Foo
有他们的B
属性设置为null
.
有一个相当“肮脏”的解决方案应该有效。这需要更改一些代码,但会留下您的Foo
具有字段的实体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
:
class FooB {
[Key, ForeignKey("FooId")]
public int FooId { get; set; }
public int B { get; set; }
}
旁注 - 将基本上单个可为空的列添加到表中似乎是非常奇怪的方式,因为没有逻辑方法FooB
可以有多个不可为空的列,这不会导致在将列值设置为空时删除整个实体。
另一种选择是创建一个行为如您所愿的数据库视图并将其映射到实体。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)