Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Core 2.0 Multiple one to one relationships

I am trying to create a model that has a Customer entity with two references to Address entities: BillingAddress and ShippingAddress.

Customer

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

    public Guid? BillingAddressId { get; set; }
    public Address BillingAddress { get; set; }

    public Guid? ShippingAddressId { get; set; }
    public Address ShippingAddress { get; set; }
}

Address

public class Address
{
    public Guid AddressId { get; set; }

    public Customer Customer { get; set; }
    public Guid CustomerId { get; set; }
}

OnModelCreating

modelBuilder.Entity<Address>(eb =>
{
    eb.HasOne(e => e.Customer).WithOne(o => o.BillingAddress).OnDelete(DeleteBehavior.Cascade);
});

modelBuilder.Entity<Address>(eb =>
{
    eb.HasOne(e => e.Customer).WithOne(o => o.ShippingAddress).OnDelete(DeleteBehavior.Cascade);
});

I get the following error when trying to create the migration:

Cannot create a relationship between 'Customer.ShippingAddress' and 'Address.Customer', because there already is a relationship between 'Customer.BillingAddress' and 'Address.Customer'. Navigation properties can only participate in a single relationship.

I'm trying to configure the model so that when the Customer is deleted the referenced Addresses are deleted as well. I would like to be able to do this without loading the Addresses into the Context and relying on the database to cascade.

like image 541
Rob Avatar asked Mar 23 '18 00:03

Rob


People also ask

How do you create a many-to-many relationship in EF core?

Many-to-many relationships require a collection navigation property on both sides. They will be discovered by convention like other types of relationships. The way this relationship is implemented in the database is by a join table that contains foreign keys to both Post and Tag .

Is EF core faster than EF6?

Note that for a single row, EF Core is slower than EF6 unless using context pooling; this could be the cost of setting up all the scoped services for each instance (which isn't done when context pooling is on). For multiple rows, EF Core batches and EF6 doesn't, so EF Core quickly becomes much faster.

What is one to many relationship in Entity Framework?

In the one-to-many relationship, each row of the principal entity table can relate with the multiple rows of the dependent database table.

What is HasPrincipalKey?

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).


1 Answers

Taken straight from here, section [InverseProperty]: https://docs.microsoft.com/en-us/ef/core/modeling/relationships

You can use the Data Annotations to configure how navigation properties on the dependent and principal entities pair up. This is typically done when there is more than one pair of navigation properties between two entity types.

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int AuthorUserId { get; set; }
    public User Author { get; set; }

    public int ContributorUserId { get; set; }
    public User Contributor { get; set; }
}

public class User
{
    public string UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [InverseProperty("Author")]
    public List<Post> AuthoredPosts { get; set; }

    [InverseProperty("Contributor")]
    public List<Post> ContributedToPosts { get; set; }
}
like image 175
Madison Haynie Avatar answered Oct 10 '22 08:10

Madison Haynie