Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to Determine Principal End - Entity Framework Code First Relationship

PLEASE CHECK POSSIBLE SOLUTION SECTION BELOW

I have an issue with a foreign key relationship - here are my tables:

public class Lead
{
    [Key]
    public int LeadId { get; set; }
    public int? CustomerId { get; set; }

    [ForeignKey("CustomerId")]
    public virtual Customer Customer { get; set; }
 }

public class Customer
{
    [Key]
    [Column("customer_id")]
    public int CustomerId { get; set; }

    [ForeignKey("CustomerId")]
    public virtual Lead Lead { get; set; }

}

I'm having an issue where I receive this error:

Unable to determine the principal end of an association between the types 'Sales.Customers.Customer' and 'Sales.Leads.Lead'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

I've tried adding the relationship to the modelbuilder but it appears that its not working properly. When I do get the error message to go away its actually using the Lead.LeadId -> Customer.CustomerId as the relationship instead of Lead.CustomerId -> Customer.CustomerId relationship.

I've checked similar questions on Stackoverflow but they don't seem to match my DB structure and when I try to implement their suggestions the relationship still doesn't work properly.

Its really weird - would greatly appreciate help on this!

UPDATE

So in my attempt to get this relationship to work I've switched the keys around in the following way:

public class Lead
{
    [Key]
    public int LeadId { get; set; }

    [ForeignKey("LeadId")]
    public virtual Customer Customer { get; set; }
}

public class Customer
{
    [Key]
    [Column("customer_id")]
    public int CustomerId { get; set; }
    public int? LeadId { get; set; }

    [ForeignKey("LeadId")]
    public virtual Lead Lead { get; set; }
}

However, same error, still no luck - I'm really at a loss why this relationship won't work. To me it seems pretty straight forward.

UPDATE 2

Ok - after a TON of wasted time messing with this I've tried a slightly different approach:

Here are my new classes....

    public class Lead
    {
        [Key, ForeignKey("Customer")]
        public int LeadId { get; set; }
        public virtual Customer Customer { get; set; }
    }

    public class Customer
    {
        [Key]
        [Column("customer_id")]
        public int CustomerId { get; set; }
        public int? LeadId { get; set; }
        public virtual Lead Lead { get; set; }
     }

No more error messages with the code above! The only problem is that the relationship entity framework is creating is between the Customer.CustomerId and Lead.LeadId instead of the Customer.LeadId and Lead.LeadId - I feel like i'm SO CLOSE!

POSSIBLE SOLUTION

Ok - so after some more research I came across this post here: EF Code First - 1-to-1 Optional Relationship

I modified my classes to this:

public class Customer
{
    [Key]
    [Column("customer_id")]
    public int CustomerId { get; set; }

    public virtual Lead Lead { get; set; }
}

public class Lead
{
    [Key]
    public int LeadId { get; set; }
    public virtual Customer Customer { get; set; }
 }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Customer>().HasOptional<Lead>(l => l.Lead).WithOptionalDependent(c => c.Customer).Map(p => p.MapKey("LeadId"));
    base.OnModelCreating(modelBuilder);
}

Everything works GREAT! But one BIG problem...

I had to remove the LeadId property from the Customer Table.... so now I'm not sure how I can assign a LeadId when creating a new Customer (when appropriate) if there is no LeadId property to assign to?

like image 772
99823 Avatar asked Nov 02 '22 18:11

99823


1 Answers

Posting this in fluent API, it should work.

public class Lead
{
    [Key]
    public int LeadId { get; set; }

    public virtual Customer Customer { get; set; }
 }

public class Customer
{
    [Key]
    [Column("customer_id")]
    public int CustomerId { get; set; }

    public virtual Lead Lead { get; set; }
}

builder.Entity<Lead>()
.HasOptional(l => l.Customer)
.WithOptionalPrincipal()
.Map(k => k.MapKey("LeadId"));

builder.Entity<Customer>()
.HasOptional(c => c.Lead)
.WithOptionalPrincipal()
.Map(k => k.MapKey("CustomerId"));

EDIT

Tables

like image 163
SOfanatic Avatar answered Nov 15 '22 07:11

SOfanatic