I have been searching for resources on how to declare foreign key relationships and other constraints using code first EF 4.1 without much luck. Basically I am building the data model in code and using MVC3 to query that model. Everything works via MVC which is great (kudos to Microsoft!) but now I want it NOT to work because I need to have data model constraints.
For example, I have a Order object that has a ton of properties that are external objects (tables). Right now I can create an Order no problem, but without being able to add the foreign key or external objects. MVC3 sets this up no problem.
I realize that I could just add the objects myself in the controller class prior to save, but I would like the call to DbContext.SaveChanges() to fail if the constraint relationships have not been met.
NEW INFORMATION
So, specifically, I would like an exception to occur when I attempt to save an Order object without specifying a customer object. This does not seem to be the behavior if I just compose the objects as described in most Code First EF documentation.
Latest code:
public class Order { public int Id { get; set; } [ForeignKey( "Parent" )] public Patient Patient { get; set; } [ForeignKey("CertificationPeriod")] public CertificationPeriod CertificationPeriod { get; set; } [ForeignKey("Agency")] public Agency Agency { get; set; } [ForeignKey("Diagnosis")] public Diagnosis PrimaryDiagnosis { get; set; } [ForeignKey("OrderApprovalStatus")] public OrderApprovalStatus ApprovalStatus { get; set; } [ForeignKey("User")] public User User { get; set; } [ForeignKey("User")] public User Submitter { get; set; } public DateTime ApprovalDate { get; set; } public DateTime SubmittedDate { get; set; } public Boolean IsDeprecated { get; set; } }
This is the error I get now when accessing the VS generated view for Patient:
ERROR MESSAGE
The ForeignKeyAttribute on property 'Patient' on type 'PhysicianPortal.Models.Order' is not valid. The foreign key name 'Parent' was not found on the dependent type 'PhysicianPortal.Models.Order'. The Name value should be a comma separated list of foreign key property names.
Regards,
Guido
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.
Step 1 − First, create the console application from File → New → Project… Step 2 − Select Windows from the left pane and Console Application from the template pane. Step 3 − Enter EFCodeFirstDemo as the name and select OK. Step 4 − Right-click on your project in the solution explorer and select Manage NuGet Packages…
Foreign Key Basics In the Authors table, which is a primary table, the AuthorId column is a primary key (PK). In the Books table (a foreign table), the AuthorId column is a foreign key ( FK ). Let's look at some data. The Books table assigns an author to each book using the AuthorId column.
If you have an Order
class, adding a property that references another class in your model, for instance Customer
should be enough to let EF know there's a relationship in there:
public class Order { public int ID { get; set; } // Some other properties // Foreign key to customer public virtual Customer Customer { get; set; } }
You can always set the FK
relation explicitly:
public class Order { public int ID { get; set; } // Some other properties // Foreign key to customer [ForeignKey("Customer")] public string CustomerID { get; set; } public virtual Customer Customer { get; set; } }
The ForeignKeyAttribute
constructor takes a string as a parameter: if you place it on a foreign key property it represents the name of the associated navigation property. If you place it on the navigation property it represents the name of the associated foreign key.
What this means is, if you where to place the ForeignKeyAttribute
on the Customer
property, the attribute would take CustomerID
in the constructor:
public string CustomerID { get; set; } [ForeignKey("CustomerID")] public virtual Customer Customer { get; set; }
EDIT based on Latest Code You get that error because of this line:
[ForeignKey("Parent")] public Patient Patient { get; set; }
EF will look for a property called Parent
to use it as the Foreign Key enforcer. You can do 2 things:
1) Remove the ForeignKeyAttribute
and replace it with the RequiredAttribute
to mark the relation as required:
[Required] public virtual Patient Patient { get; set; }
Decorating a property with the RequiredAttribute
also has a nice side effect: The relation in the database is created with ON DELETE CASCADE
.
I would also recommend making the property virtual
to enable Lazy Loading.
2) Create a property called Parent
that will serve as a Foreign Key. In that case it probably makes more sense to call it for instance ParentID
(you'll need to change the name in the ForeignKeyAttribute
as well):
public int ParentID { get; set; }
In my experience in this case though it works better to have it the other way around:
[ForeignKey("Patient")] public int ParentID { get; set; } public virtual Patient Patient { get; set; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With