Reputation: 1159
Please don't mark this as a duplicate issue. I have scoured through every other relevant post I can find on SO, tried proposed and accepted solutions - none of it has worked for me.
My data model is such that an ApplicationUser may or may not be a Driver and a Driver must be an ApplicationUser. ApplicationUser is the Principal and Driver is the Dependent.
public class ApplicationUser
{
public int Id { get; set; }
public virtual Driver Driver { get; set; }
}
public class Driver
{
public int Id{ get; set; }
public virtual ApplicationUser User { get; set; }
}
In the physical domain, there should be no other keys (PK or FK) other than the Ids.
I believe that EF models this as making the Id property of Driver be the PK and FK, so quite logically, an ApplicationUser has to exist first and its PK can be used as the PK of the Driver, too.
I have tried all variations of fluent modeling on SO posts and I mostly get the error that roughly says "[you need to mark one side as the principal]".
This works when I put a [Required] attribute above ApplicationUser property in the Driver class.
I just can't seem to find the right fluent mapping statements to emulate that.
One would think initially that this should do it, but it doesn't:
modelBuilder.Entity<Driver>()
.HasRequired(e => e.User)
.WithOptional(e=> e.Driver);
I would think that the HasRequired(e => e.User) is the same thing for the [Required] property but I guess not...
I am wondering if this can possibly be a bug in EF 6.1.3.
Any suggestions would be very much appreciated.
Thanks
Upvotes: 2
Views: 278
Reputation: 764
These mappings should work
public class ApplicationUserMap : EntityTypeConfiguration<ApplicationUser>
{
public ApplicationUserMap()
{
this.HasOptional(x => x.Driver)
.WithOptionalPrincipal()
.Map(x => x.MapKey("Id"));
}
}
public class DriverMap : EntityTypeConfiguration<Driver>
{
public DriverMap()
{
this.HasOptional(x => x.ApplicationUser)
.WithOptionalPrincipal()
.Map(x => x.MapKey("Id"));
}
}
Update from comments
As you mentioned in your question, you have a principle and dependant entity. The problem is that EF does not know which is which in a one or zero to one relationship and so you need to use Data Annotations. To do this, change your Driver class to this:
public class Driver
{
[Key, ForeignKey("ApplicationUser")]
public int Id{ get; set; }
public virtual ApplicationUser User { get; set; }
}
As you are not using EF naming conventions, I would also suggest you changing the name of your ID's to ApplicationUserID
and DriverID
as Nick L mentioned in his answer before you try this if you haven't done so already.
I'm not fully sure, but if that works, you may not need to use Fluent mappings.
Upvotes: 1
Reputation: 6015
Well, I think it is not the same. HasRequired
is used mostly in order to apply 0..1-N
mappings. You can try IsRequired
instead in your configuration:
Property(e => e.User).IsRequired();
UPDATE: Another issue is that you are not giving Ids in your classes following the convention ClassNameID
in order for the EF to map it automatically. You should have ApplicationUserID
and DriverID
, otherwise you have to set a mapping on your fluent API configuration on the principal, as sleaver suggested.
Upvotes: 0