Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Code First - Defining Relationships/Keys

I am designing my database using code first and I need a little help I think.

I am getting this error:

Introducing FOREIGN KEY constraint 'SalesOrder_Invoices' on table 'Invoices' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.

I am trying to have the following relationships/keys:

--> = 1 to Many Relationship 
  1. Customer --> CustomerLocation
  2. CustomerLocation --> SalesOrder
  3. SalesOrder --> Invoice
  4. SalesRep --> SalesOrder
  5. PaymentTerm --> Customer
  6. PaymentTerm --> SalesOrder
  7. PaymentTerm --> Invoice

I am trying to define them by the standard of:

<ClassName><PrimaryKeyID> 

Example: Customer has ID property, so in CustomerLocation i define the foreign key like so:

Public Property CustomerID AS Integer 

All I have to do is define the foreign key correct? Do I also have to have navigation properties for each key I define?

And, can I not have multiple foreign keys on the same primary key of an object?

Updated

So to define a relationship, do you use the ClassName.PrimaryKeyProperty? or do you use navigation properties? Or both? Confused!!

Update 2

So to make a relationship work you have to define both sides... I think.

Public Class Customer     Public Property ID AS Integer     Public Overrideable Property Locations AS ICollection(OF CustomerLocation)  End Class  Public Class CustomerLocation     Public Property ID AS Integer     Public Property CustomerID AS Integer  End Class 
like image 911
Sam Avatar asked Apr 03 '11 21:04

Sam


People also ask

How do you create a foreign key relationship in code first approach?

To create Foreign Key, you need to use ForeignKey attribute with specifying the name of the property as parameter. You also need to specify the name of the table which is going to participate in relationship. I mean to say, define the foreign key table. Thanks for reading this article, hope you enjoyed it.

How do I set primary key in Entity Framework?

Use the ColumnAttribute or the HasKey method to specify an order for composite primary keys. In order to use composite keys, Entity Framework requires you to define an order for the key properties. You can do this by using the Column annotation to specify an order.

What is many to many relationships in code first approach?

A many-to-many relationship occurs when multiple records in one table are associated with multiple records in another table. For example, a many-to-many relationship exists between Book and Category entities.


2 Answers

This is exception caused by SQL server when you have multiple paths of cascade deletes. If you delete your PaymentTerm it will trigger cascade delete on all three relations. This will blow up when creating either SalesOrder or Invoice. EF creates by default all one-to-many relations with ON DELETE CASCADE you can remap your specific relation to not use it by:

modelBuilder.Entity<...>()             .HasRequired(...)             .WithMany(...)             .HasForeignKey(...)             .WillCascadeOnDelete(false); 

Or you can turn it off globaly by removing the convention:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();    

You can get around this error on a particular migration by editing the generated Up() method with a line something like this:

AddForeignKey("dbo.Payments", "EventID", "dbo.Events", "EventID", cascadeDelete: true) 

and change that cascadeDelete: value to false on the offending relationship(s).

like image 151
Ladislav Mrnka Avatar answered Oct 05 '22 19:10

Ladislav Mrnka


Read this, I am sure this will help you find the answer.

Also, according to ScottGu's blogpost, I think in general it should be that you just create the classes as follows (I didn't read it carefully enough, so you should check it out for further details):

public class Customer {     public int CustomerID { get; set; }     public int CustomerLocationID { get; set; }     public virtual CustomerLocation Location { get; set; } }  public class CustomerLocation {     public int CustomerLocationID { get; set; }     public virtual ICollection<Customer> Customers { get; set; } } 
like image 42
Shimmy Weitzhandler Avatar answered Oct 05 '22 21:10

Shimmy Weitzhandler