问题
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:
to this logical object model:
which I have tried setting up as follows: (I hope the German captions won't be too disorienting.)
Entity Framework gives me this error:
Error 3031: Problem in mapping fragments …: Non-nullable column
FooBs.B
in tableFooBs
is mapped to a nullable entity property.
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?
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"); }); }
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 insertNULL
intoFooBs.B
for allFoo
that have theirB
property set tonull
.
回答1:
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; }
}
And mapped to database class FooB
:
class FooB {
[Key, ForeignKey("FooId")]
public int FooId { get; set; }
public int B { get; set; }
}
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.
来源:https://stackoverflow.com/questions/23137775/nullable-scalar-navigation-properties-in-ef-4-0-mapping-a-non-nullable-column