I am trying to set up an Entity Framework model with an optional:optional relationship:
In my situation, sometimes an AdditionalData record exists that points to a BaseTable record, but sometimes BaseTable or AdditionalData records exist without any linkage. The foreign key to the BaseTable (if it exists) is on the AdditionalData table.
I want to be able to navigate back and forth between BaseTable and any AdditionalDatas that might be connected.
BaseTable 0..1 ----- 0..1 AdditionalData1
\
--- 0..1 AdditionalData2
public class BaseTable {
public int Id { get; set; }
public virtual AdditionalType1 AdditionalType1 { get; set; }
public virtual AdditionalType2 AdditionalType2 { get; set; }
}
public class AdditionalType1 {
public int Id { get; set; }
public int? BaseTableId { get; set; }
public virtual BaseTable BaseTable { get; set; }
}
public class AdditionalType2 {
public int Id { get; set; }
public int? BaseTableId { get; set; }
public virtual BaseTable BaseTable { get; set; }
}
How do I make this work? I got as far as:
modelBuilder.Entity<AdditionalType1>()
.HasOptional(zmt => zmt.BaseTable)
.WithOptionalDependent(zm => zm.AdditionalType1)
.Map(a => a.MapKey("BaseTableId"));
modelBuilder.Entity<AdditionalType2>()
.HasOptional(zmt => zmt.BaseTable)
.WithOptionalDependent(zm => zm.AdditionalType2)
.Map(a => a.MapKey("BaseTableId"));
but it tells me this:
error: (1564,6) : error 0019: Each property name in a type must be unique. Property name 'BaseTableId' was already defined.
I don't know exactly what that refers to, and not sure how to fix.
EDIT: If I remove the Map/MapKey clauses as suggested here (https://stackoverflow.com/a/8016308/237091) I get this error instead, when a query runs that uses it:
Invalid column name 'BaseTable_Id' as it maps itself to BaseTable_Id automatically instead of my BaseTableId field.
HasPrincipalKey(Type, String[]) Configures the unique property(s) that this relationship targets. Typically you would only call this method if you want to use a property(s) other than the primary key as the principal property(s).
IEntityTypeConfiguration<TEntity> InterfaceAllows configuration for an entity type to be factored into a separate class, rather than in-line in OnModelCreating(ModelBuilder).
The DbContext class has a method called OnModelCreating that takes an instance of ModelBuilder as a parameter. This method is called by the framework when your context is first created to build the model and its mappings in memory.
Entity framework supports three types of relationships, same as database: 1) One-to-One 2) One-to-Many, and 3) Many-to-Many.
It looks like you're trying to set up a 1:0..1 relationship from your AdditionalType
objects (which I may have misinterpreted completely.
N.B. I think you would have to hold a BaseTableId on your BaseTable
for this to work (or define a primary key):
If BaseTableId
is the foreign key in this instance, I think this may be what you're after:
modelBuilder.Entity<AdditionalType1>()
.HasOptional(zmt => zmt.BaseTable)
.WithMany()
.HasForeignKey(a => a.BaseTableId);
Which is what I've used previously, but can't admit to understanding it fully (the .WithMany() trips me up); it's a slight workaround listed in article from this answer: Entity Framework 0..1 to 0 relation)
Apologies if I've missed the point entirely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With