Referential relationships
When you configure a reference relationship between objects in the Entity Framework, it is convenient to query the data.
However, many old systems do not display the specified foreign key, mostly by adding a Master object ID to the child object to solve the problem.
If you do not configure it at this time, it is impossible to implement the reference relationship between the two objects. Because the Entity Framework does not know that the column is used to determine the referential relationship.
So, this chapter will introduce its default rules, and it will also show you how to freely configure reference relationships.
Default rule
When you don't configure anything, the Entity Framework defaults to think of your database as:
- If your entity has a collection type navigation property for another entity, Code first considers them to be a one-to-many relationship by default;
- If one of your entities has a navigation property on another entity (not both have a navigation property of the other), Code first will also default to the relationship that they are one-to-many;
- If your two entities have each other's collection-type navigation properties, Code first will consider them to be many-to-many relationships by default;
- If you have two entities with each other's navigation properties, Code first will consider them to be a one-to-one relationship by default;
- By default, the Code first foreign key and table name (many-to-many association tables) are required.
In general: If you are building an entity and then creating a database, you can use the default rules without configuration, but if you are an existing database, it is often difficult to match exactly, and you will always need to configure something.
Use the Fluent API to configure reference relationships
The Attribute configuration method (Data Annotations) does not implement all the functions, it is recommended to use the Fluent API to implement, the specific configuration follows the standard:
Entity.HasMultiplicity.WithMultiplicity.Map (Option)
Among them, Has[multiplicity] contains the following three ways:
- Hasoptional
- Hasrequired
- Hasmany
In addition, With[multiplicity] also contains three ways:
- Withoptional
- Withrequired
- Withmany
The last map is used to map foreign keys (not display foreign keys or rows).
But how does it work? An example will be used to illustrate this later.
Configure one-to-many and one-to-one relationships
public class user{Public int ID {get; set;} public string Name {get; set;} Public virtual ilist<article> articles {get; set;}} public class article{Public int ID {get; set;} public string Name {get; set;} Public virtual User Owner {get; set;}}
The code above has two entities, which are one-to-many relationships.
The complete configuration code is as follows:
public class testcontext:dbcontext{public dbset<user> userset {get {return set<user> ();}} Public dbset<article> Articleset {get {return set<article> ();}} protected override void Onmodelcreating (Dbmodelbuilder modelBuilder) {ModelBuilder. Configurations. ADD (New Usertypeconfiguration ()). ADD (New Articletypeconfiguration ()); Base. Onmodelcreating (ModelBuilder); }}public class usertypeconfiguration:entitytypeconfiguration<user>{Public usertypeconfiguration () { Haskey (U = u.id); Property (U = u.id). IsRequired (). Hasdatabasegeneratedoption (databasegeneratedoption.identity); Hasmany (U = u.articles). withrequired (A = A.owner). Map (x = X.mapkey ("UserID")); ToTable ("User"); }}public class articletypeconfiguration:entitytypeconfiguration<article>{public articletypeconfiguration () {Haskey (a = a.id); Property (A = a.ID). IsRequired (). Hasdatabasegeneratedoption (databasegeneratedoption.identity); ToTable ("article"); }}
The other is the basic configuration, where the most critical piece of code is:
Hasmany (U = u.articles) . withrequired (A = A.owner) . Map (x = X.mapkey ("UserID"));
In fact, the semantics here is very clear, if I translate this paragraph of English directly into Chinese, I think it can be such a son.
"I have a lot of article, it has an Owner and is a must, the foreign key is mapped to the UserID"
Is it a clear relationship? In addition, the relationship between the two entities is only configured once on any one entity, but the configuration method is different.
The above is configured on the main object User, if configured on article, the statement should be written like this:
hasrequired (A = A.owner) . Withmany (U = u.articles) . Map (x = X.mapkey ("UserID"));
"I have a Owner cut is necessary, it has a lot of article, foreign keys are mapped to the UserID"
How is that one-to-one relationship configured?
In fact, one on the other is this: I have a xxx, it has a xxx, foreign keys are mapped into XXX.
hasrequired (A = A.owner) . Withoptional (U = u.article) . Map (x = X.mapkey ("UserID"));
Besides, what's the difference between hasoptional and hasrequired? The difference is that this foreign key (or non-display foreign key) is allowed to be Null.
Configuring a Many-to-many relationship
The semantics of many-to-many relationships are very simple: I have a lot of xxx, it has a lot of xxx ...
But the key is the MAP.
Because of the many-to-many, you must configure a mapping table, the specific configuration method is as follows:
Hasmany (A = a.categories) . Withmany (c = c.articles) . Map (x = x.totable ("Articlecategory") . Mapleftkey ("ArticleID") . Maprightkey ("CategoryID"));
Here in Map, you must configure the foreign key (or non-display foreign key) of the associated left table and the foreign key of the associated right table, and also specify the name of the associated table.
Overall, the configuration is also very simple!
EntityFramework Fluent Api