Step by step to implement your own ORM (v)

Source: Internet
Author: User

The previous insert, UPDATE, DELETE optimized ORM, but populating the database with values in the entity class is not optimized. In addition, Bo friends in the online consultation said that you are all query all fields, and his needs are on-demand query fields, not one-time out all the fields, here I ask this friend to wait patiently, this will be mentioned in later chapters. This time we optimize the datareader->entity, the value of the database mapping to the entity class, we commonly used to have two methods, the first is to use the Emit method, the second is to use expression tree expressions, the two schemes differ little in performance, But the second is easier to do than the first, where I use expression tree expressions to perform entity class conversion operations.

Let's start by looking at how expression expressions convert DataReader to object:

            NULL ;            ExpressionNew  User ()            {                = R.getint32 (0),                = R.getdatetime ( 1 ),                = r.getstring (2),            };             var func = expr.compile ();            Func (reader);

In the new user when the object is initialized to assign values to the property, and in the actual project we will encounter more complex, such as to determine whether it is dbnull, or the conversion will be wrong, here I define a getvalue<t> (int i) method, specifically to do the value operation.

    classDbfieldreader {PrivateIDataReader Reader;  PublicDbfieldreader (IDataReader reader) { This. Reader =reader; }         PublicT getvalue<t> (intindex) {            ObjectValue =Reader.            GetValue (index); if(Value = =DBNull.Value)return default(T); return(T) reader.        GetValue (index); }    }

Now the code is modified,

IDataReader reader =NULL; Dbfieldreader FR=NewDbfieldreader (reader); Expression<func<dbfieldreader, user>> expr = (r) = =NewUser () {UserId= r.getvalue<int> (0), Createdtime= R.getvalue<datetime> (1), Email= r.getvalue<string> (2),            }; varFunc =Expr.compile (); Func (FR);

Is it a lot more concise? Transfer the judgment code to the Dbfieldreader class, now we are going to convert this method into a generic entity class, first to decompose expression expressions (such as throwing up errors, begging the great God).

The first step defines the parameter, type Dbfieldreader, parameter name: R

ParameterExpression parexpr = Expression.parameter (typeof"R");

In the second step, call the constructor of the user class with the following code:

var newexpr = expression.new (type. GetConstructors (). First ());

Merge these 2 expressions and run the results:

Expression<func<dbfieldreader, user>> expr = (Expression<func<dbfieldreader, User>>) Expression.lambda (newexpr, parexpr);

The basic prototype came out, now to do is to assign value to the attribute, how come? First, a simple one is to give a fixed value.

var userid = Expression.bind (type. GetProperty ("UserId"), Expression.constant (1typeof(int))) ;

This is equivalent to the assignment operation of UserID = 1, which continues to merge expressions:

          varType =typeof(User); ParameterExpression parexpr= Expression.parameter (typeof(Dbfieldreader),"R"); varnewexpr =expression.new (type. GetConstructors ().            First ()); varUserID = Expression.bind (type. GetProperty ("UserId"), Expression.constant (1,typeof(int))); varCreatedtime = Expression.bind (type. GetProperty ("Createdtime"), Expression.constant (DateTime.Now,typeof(DateTime))); varinit =Expression.memberinit (newexpr, UserID, createdtime); Expression<func<dbfieldreader, user>> expr = (Expression<func<dbfieldreader, user>>) Expression.Lambda (init, parexpr);

After the constant assignment is not a problem, the following method is called.

            var typeof " GetValue " && C.isgenericmethod). First ();             var callexpr = Expression.call (parexpr, method. MakeGenericMethod (typeof(int.)), Expression.constant (0));
var UserID = Expression.bind (type. GetProperty ("UserId"), callexpr);

This sentence is equivalent to r.getvalue<int> (0);

Get the GetValue method first, then call MakeGenericMethod to generate the generic method, Expression.constant (0) is the parameter value.

Full version of the code:

IDataReader reader =NULL; Dbfieldreader FR=NewDbfieldreader (reader); varentitymapping = attributemapping.get<user>(); ParameterExpression parexpr= Expression.parameter (typeof(Dbfieldreader),"R"); varnewexpr =expression.new (EntityMapping.EntityType.GetConstructors ().            First ()); varMETHOD =typeof(Dbfieldreader). GetMethods (). Where (c = c.name = ="GetValue"&&C.isgenericmethod).            First (); List<MemberBinding> memberbindings =NewList<memberbinding>(); intindex =0; foreach(varIteminchentitymapping.members) {varcallexpr =Expression.call (parexpr, method. MakeGenericMethod (item.                Member.propertytype), Expression.constant (index)); varMemberassignment =Expression.bind (item.                Member, callexpr);                Memberbindings.add (memberassignment); Index++; }            varinit =Expression.memberinit (newexpr, memberbindings); Expression<func<dbfieldreader, user>> expr = (Expression<func<dbfieldreader, user>>) Expression.Lambda (init, parexpr);

Of course we also need to modify the SQL statement, not with the SELECT * syntax, but to use the syntax of select Userid,email...from

The final code code download:

Http://files.cnblogs.com/files/sobaby/ORM05.zip

Step by step to implement your own ORM (v)

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.