Step by Step EF Series "4, upgrade entity and database mapping" Live writer Real Pit, 4th time reissue

Source: Internet
Author: User

Objective

Before a few articles, was recommended to the home page, and was under the blog park, the reason content is too little, then I want to write more, or to follow this frequency to write it? itself my intentions this series is to have the simplest and easiest to understand the way to carry out, each content also do not too much, so that beginners easy to understand learning, or the hype of a large beginner from the beginning to see the tail will be dizzy. So every time I focus on the concentration of the essence of the talk, of course, I am so concise, you have to learn in-depth, but also to some of the concepts to learn more deeply. We also welcome you to discuss the study together. I created a QQ group here (435498053), we can also add group communication.

Body

This article or as a previous upgrade, in fact, the previous 2-3 can be merged, but I think the direct merger is not easy to understand, first to the most basic, and then in a gradual and progressive in-depth and code aspects of the encapsulation simplification. We don't talk about it, and then the last part of the article, you remember the final written code? I'll post the code and review it.

       Entity Collection Public        idbset<bloguser> blogusers {get; set;}        Public idbset<post> Posts {get; set;}             <summary>///Rewrite configuration class////</summary>//        <param name= "ModelBuilder" ></param>        protected override void Onmodelcreating (Dbmodelbuilder modelBuilder)        {            //base. Onmodelcreating (ModelBuilder);            MODELBUILDER.CONFIGURATIONS.ADD (New Bloguserconfiguration ());            MODELBUILDER.CONFIGURATIONS.ADD (New Postconfiguration ());        }

The previous article we put forward this is to simplify the onmodelcreating in the configuration of each table to write here, but the intentions of friends should see, you write this is actually still very troublesome ah! According to the current writing, do I have to create a collection of entities here, and then join a MODELBUILDER.CONFIGURATIONS.ADD (new Xxxconfiguration ()) below, so the problem remains the same. specifically see below

As can be seen from the code, the current context class is strongly coupled to the business entity, and is coupled to the dbset<tentity> attribute and onmodelcreating method respectively. What about the solution? Of course to decouple. For attributes, you can use the Dbcontext.set<tentity> () method to implement the properties of the specified entity, and for a mapping configuration object in a method implementation in Onmodelcreating, you can extract a common interface that is mapped separately through the interface. Then we'll take two steps to explain how to decouple!

One, the extraction of a Ientitymapper universal interface, through the interface to map separately.

1, the code to define the interface is as follows:

    <summary>//     Entity Mapping interface///</summary> public    interface ientitymapper    {        // <summary>////     Register the current entity mapping object with the current data access context entity mapping Configuration Registrar///</summary>//        <param name= " Configurations "> Entity Mapping Configuration Registrar </param>        void Registto (Configurationregistrar configurations);    }

2. Add the implementation of Ientitymapper to the entity mapping class. We have Bloguser as an example demonstration. The code is as follows

<summary>    ///blog User Information mapping class    ///</summary> public class Bloguserconfiguration: Entitytypeconfiguration<bloguser>,ientitymapper    {public        bloguserconfiguration ()        {            //Set Primary key            Haskey (m = M.bloguserid);        }        public void Registto (System.Data.Entity.ModelConfiguration.Configuration.ConfigurationRegistrar configurations)        {            configurations. ADD (this);            throw new NotImplementedException ();        }    }

3, so defined, that is not to be considered how can be automatically called in onmodelcreating implementation Ientitymapper automatic registration it! There are many ways to do this, and there are friends who know that IOC should think of using dependency injection to introduce all the objects that implement the Ientitymapper class. But I'm not going to do this with the IOC component first, we'll do it in the most traditional way.

How exactly do we have to do it all? is to introduce all the objects that implement the Ientitymapper class, and then iterate through the Registto to add the entity mapping class object.

The first step is to get all the objects that implement the Ientitymapper class, see the Code

 private static icollection<ientitymapper> Getallentitymapper () {icollection<assembly > entitymapperassemblies = entitymapperassemblies = new[] {Assembly.            LoadFrom (Path.Combine (AppDomain.CurrentDomain.RelativeSearchPath, "EFCore.dll")}; if (Entitymapperassemblies.count = = 0) {throw new InvalidOperationException ("context" {0} "initialization failed, please add the actual            Volume mapping assembly ");            } Type BaseType = typeof (Ientitymapper); type[] Mappertypes = entitymapperassemblies.selectmany (assembly = assembly. GetTypes ()). Where (type = Basetype.isassignablefrom (type) && type! = BaseType &&!type. IsAbstract).            ToArray (); icollection<ientitymapper> result = Mappertypes.select (type = Activator.CreateInstance (type) as Ientitymapper).            ToList ();        return result; }

Above this paragraph I refer to someone else's code, specific which blog I do not remember, then find me on the Add Reference. The principle is also relatively simple is I load I write entity class EFCore.dll assembly, this DLL name is based on the DLL name of your actual project, this name is now my own demo. It then finds the class that implements Ientitymapper and then creates an instance of that type through CreateInstance, which is the principle.

The second step, traversing the object, calls the Registto in which the entity mapping class object is added

<summary>///Rewrite configuration class////</summary>//        <param name= "ModelBuilder" ></param>        protected override void Onmodelcreating (Dbmodelbuilder modelBuilder)        {            //base. Onmodelcreating (ModelBuilder);            MODELBUILDER.CONFIGURATIONS.ADD (New Bloguserconfiguration ());            MODELBUILDER.CONFIGURATIONS.ADD (New Postconfiguration ());            Modelbuilder.entity<bloguser> (). Haskey (M = m.bloguserid);            ienumerable<ientitymapper> entitymappers = Getallentitymapper ();            if (entitymappers = = null)            {                return;            }            foreach (var mapper in entitymappers)            {                mapper. Registto (modelbuilder.configurations);            }        }

Then it's done, run your code. Did it succeed too.

I put the complete code in the attached

        <summary>///Rewrite configuration class///</summary>//<param name= "ModelBuilder" ></ param> protected override void Onmodelcreating (Dbmodelbuilder modelBuilder) {//base.            Onmodelcreating (ModelBuilder);            MODELBUILDER.CONFIGURATIONS.ADD (New Bloguserconfiguration ());            MODELBUILDER.CONFIGURATIONS.ADD (New Postconfiguration ()); Modelbuilder.entity<bloguser> ().            Haskey (M = M.bloguserid);            ienumerable<ientitymapper> entitymappers = Getallentitymapper ();            if (entitymappers = = null) {return; } foreach (var mapper in entitymappers) {mapper.            Registto (modelbuilder.configurations); }} private static Icollection<ientitymapper> Getallentitymapper () {icollection<               assembly> entitymapperassemblies = Entitymapperassemblies = new[]         {Assembly.LoadFrom (Path.Combine (AppDomain.CurrentDomain.RelativeSearchPath, "EFCORE.D            ll "))}; if (Entitymapperassemblies.count = = 0) {throw new InvalidOperationException ("context" {0} "initialization failed, please add the actual            Volume mapping assembly ");            } Type BaseType = typeof (Ientitymapper); type[] Mappertypes = entitymapperassemblies.selectmany (assembly = assembly. GetTypes ()). Where (type = Basetype.isassignablefrom (type) && type! = BaseType &&!type. IsAbstract).            ToArray (); icollection<ientitymapper> result = Mappertypes.select (type = Activator.CreateInstance (type) as Ientitymapper).            ToList ();        return result; }

As a demo, I don't want to create a new class to encapsulate, so it's easy to read.

Second, for attributes, you can use the Dbcontext.set<tentity> () method to implement the properties of the specified entity

Above, we realize the decoupling of the code inside the onmodelcreating by advancing a Ientitymapper interface. So here we have to find a way to deal with the code below.

Public idbset<bloguser> blogusers {get; set;} Public idbset<post> Posts {get; set;} ......

As mentioned above, the solution is to implement the properties of the specified entity through the dbcontext.set<tentity> () method, how to do it? In fact, this is much simpler than processing the configuration class, of course, or directly look at the code.

Public ActionResult Index () {    var db= new Blogdbcontext ();   Return View (db. Posts.tolist ());}
This code is the first one inside, gets the data inside the posts, and then returns the foreground display. Do you remember? Don't remember to turn to the first article to see.


The code above has been seen in the first one, and if it's decoupled, it's in db. Posts does not exist, then how to do it! Same look at the code

Public ActionResult Index ()        {            var dbContext = new Blogdbcontext ();            IQueryable
<Post> Posts = dbcontext.set<post>
();            Return View (Posts.tolist ());        }

This is what it says. Use the Dbcontext.set<tentity> () method to implement the properties of the specified entity. Is it simple? A word can be done.

Finally, I'll post our final source code.
Public Blogdbcontext (): Base () {}///entity Collection//public idbset<bloguser> blogusers {g Et Set        }//public idbset<post> Posts {get; set;} <summary>///Rewrite configuration class///</summary>//<param name= "ModelBuilder" ></param&gt        ; protected override void Onmodelcreating (Dbmodelbuilder modelBuilder) {//base.            Onmodelcreating (ModelBuilder);            MODELBUILDER.CONFIGURATIONS.ADD (New Bloguserconfiguration ());            MODELBUILDER.CONFIGURATIONS.ADD (New Postconfiguration ()); Modelbuilder.entity<bloguser> ().            Haskey (M = M.bloguserid);            ienumerable<ientitymapper> entitymappers = Getallentitymapper ();            if (entitymappers = = null) {return; } foreach (var mapper in entitymappers) {mapper.            Registto (modelbuilder.configurations);        }        }private static icollection<ientitymapper> Getallentitymapper () {icollection<assembly> Entit Ymapperassemblies = Entitymapperassemblies = new[] {assembly.loadfrom (P Ath.            Combine (AppDomain.CurrentDomain.RelativeSearchPath, "EFCore.dll")}; if (Entitymapperassemblies.count = = 0) {throw new InvalidOperationException ("context" {0} "initialization failed, please add the actual            Volume mapping assembly ");            } Type BaseType = typeof (Ientitymapper); type[] Mappertypes = entitymapperassemblies.selectmany (assembly = assembly. GetTypes ()). Where (type = Basetype.isassignablefrom (type) && type! = BaseType &&!type. IsAbstract).            ToArray (); icollection<ientitymapper> result = Mappertypes.select (type = Activator.CreateInstance (type) as Ientitymapper).            ToList ();        return result; }

Now if you add a new entity class, you don't have to change any of the code here. has been completely decoupled. Isn't it pretty simple.

Conclusion

After this article, in fact, the most basic version of EF learning is finished. The previous few also hope that beginners can master. In the following words to explain in depth, then will talk about the IOC, and Repository,unitofwork,dbcontext. These are also used in our official projects.

You are welcome to exchange. More support. QQ Group (435498053)

Step by Step EF Series "4, upgrade entity and database mapping" Live writer Real Pit, 4th time reissue

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.