How should I declare relationships with foreign keys using the code structure of the first object (4.1) in MVC3?

I was looking for resources on how to declare foreign key relationships and other constraints, using EF 4.1 code first without much luck. I basically create a data model in code and using MVC3 to query this model. Everything works through MVC, which is great (Microsoft prestige!), But now I want it to NOT work, because I need to have data model limitations.

For example, I have an Order object that has a ton of properties that are external objects (tables). Right now I can create an order without problems, but without the ability to add a foreign key or foreign objects. MVC3 does not pose any problems.

I understand that I could just add objects myself to the controller class before saving, but I would like the call to DbContext.SaveChanges () to fail if the constraint relationship was not met.

NEW INFORMATION

So, in particular, I would like an exception to occur when I try to save an Order object without specifying a client object. This doesn't seem to be behavior if I just compose the objects as described in most Code First EF docs.

Last 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 that I get now when accessing the created VS representation for the patient:

ERROR MESSAGE

The ForeignKeyAttribute property of the "Patient" property of the type "PhysicianPortal.Models.Order" is not valid. The foreign key name "Parent" was not found on the dependent type 'PhysicianPortal.Models.Order. The value of the name must be a comma separated list of the names of the foreign key properties.

Hello,

Guido

+86
asp.net-mvc-3 ef-code-first
Apr 04 2018-11-18T00:
source share
2 answers

If you have an Order class, adding a property that refers to another class in your model, for example, Customer should be enough so that EF knows the relationship 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 put it on a foreign key property, it represents the name of the associated navigation property. If you put it in a navigation property, it represents the name of the associated foreign key.

This means that if you put ForeignKeyAttribute in the Customer property, the attribute will take CustomerID in the constructor:

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



EDIT based on the last code You get this error because of this line:

 [ForeignKey("Parent")] public Patient Patient { get; set; } 

EF will look for a property called Parent to use as a foreign key tool. You can do 2 things:

1) Remove ForeignKeyAttribute and replace it with RequiredAttribute to mark the relationship as necessary:

 [Required] public virtual Patient Patient { get; set; } 

Decorating a property with RequiredAttribute also has a nice side effect: a relation in the database is created using 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 this case, it probably makes sense to call it, for example, ParentID (you will also need to change the name in ForeignKeyAttribute ):

 public int ParentID { get; set; } 

In my experience, in this case, although it’s better to work with it differently:

 [ForeignKey("Patient")] public int ParentID { get; set; } public virtual Patient Patient { get; set; } 
+146
Apr 04 2018-11-11T00:
source share

You can define a foreign key:

 public class Parent { public int Id { get; set; } public virtual ICollection<Child> Childs { get; set; } } public class Child { public int Id { get; set; } // This will be recognized as FK by NavigationPropertyNameForeignKeyDiscoveryConvention public int ParentId { get; set; } public virtual Parent Parent { get; set; } } 

Now ParentId is a foreign key property and defines the required relationship between the child and the existing parent. Saving a child without an exsiting parent will throw an exception.

If your FK property name does not consist of the navigation property name and the parent name PK, you must either use the ForeignKeyAttribute data annotation or a free API to map the relationship

Data Annotations:

 // The name of related navigation property [ForeignKey("Parent")] public int ParentId { get; set; } 

Fluent API:

 modelBuilder.Entity<Child>() .HasRequired(c => c.Parent) .WithMany(p => p.Childs) .HasForeignKey(c => c.ParentId); 

Other types of constraints can be met using data annotations and model validation .

Edit:

You will get an exception if you do not set ParentId . Property required (not null). If you just don’t install it, most likely you will try to send the default value to the database. The default value is 0, so if you do not have a client with Id = 0, you will get an exception.

+27
Apr 04 2018-11-11T00:
source share



All Articles