How to add one to many relationship based on custom property

c# entity-framework entity-framework-core foreign-keys

Question

Lets say I have two entities:

public class Customer
{
     public int CustomerId { get; set; }
     public Guid CustomerKey { get; set; }

     public ICollection<Product> Products { get; set; }
}

public class Product
{
     public int ProductId { get; set; }
     public Guid CustomerKey { get; set; }
     public string Name { get; set; }
}

1 customer can have many products, but I want to bind them based on CustomerKey property. Here is sample of example data:

CustomerId | CustomerKey
    1      | {00000000-0000-0000-0000-111111111111}
    2      | {00000000-0000-0000-0000-222222222222}

ProductId  | Name     | CustomerKey
    1      | Product1 | {00000000-0000-0000-0000-111111111111}
    2      | Product2 | {00000000-0000-0000-0000-111111111111}
    3      | Product3 | {00000000-0000-0000-0000-222222222222}

So first customer has first two products and the second customer has the last product. I tried doing something like:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Customer>().HasMany(m => m.Products);
}

But how do I specify that I want to bind them on CustomerKey?

1
2
9/4/2018 10:32:11 AM

Popular Answer

It's possible, but only if the CustomerKey property (column) of the Customer is unique. This is EF Core requirement (actually relational database FK requirement, but EF Core supports only relationships which can be represented as relational database FK constraints), so if it's not, then what you are asking is not possible.

The fluent API for that is HasPrincipalKey method:

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). If the specified property(s) is not already a unique constraint (or the primary key) then a new unique constraint will be introduced.

And of course the FK is configured as usual with HasForeignKey.

Applying it to your model:

modelBuilder.Entity<Customer>()
    .HasMany(customer => customer.Products)
    .WithOne() // no navigation property
    .HasForeignKey(product => product.CustomerKey)
    .HasPrincipalKey(customer => customer.CustomerKey);
1
9/4/2018 11:41:08 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow