SqlDataReader generates dynamic Lambda expressions and dynamically generates lambda expressions

Source: Internet
Author: User

SqlDataReader generates dynamic Lambda expressions and dynamically generates lambda expressions

The previous flat uses a dynamic lambda expression to convert a able to an object, which is much faster than directly using reflection. The delegation is dynamically generated during the first line conversion.

The subsequent conversions all call the delegate directly, saving the performance loss caused by multiple reflections.

Today, SQL Server processes the stream object SqlDataReader returned by SQL Server, and dynamically generates Lambda expressions to convert objects.

Previous Version of code

Using System; using System. collections. generic; using System. data; using System. data. common; using System. data. sqlClient; using System. linq; using System. linq. expressions; using System. reflection; using System. text; using System. threading. tasks; namespace Demo1 {public static class EntityConverter {# region // <summary> // DataTable to generate an object // </summary> /// <typeparam name = "T"> </typeparam> // <param name = "d AtaTable "> </param> // <returns> </returns> public static List <T> ToList <T> (this DataTable dataTable) where T: class, new () {if (dataTable = null | dataTable. rows. count <= 0) throw new ArgumentNullException ("dataTable", "Expression Tree cannot be generated when the current object is null"); Func <DataRow, T> func = dataTable. rows [0]. toExpression <T> (); List <T> collection = new List <T> (dataTable. rows. count); foreach (DataRow dr in dataTable. rows) {Collection. add (func (dr);} return collection ;} /// <summary> /// generate the expression /// </summary> /// <typeparam name = "T"> </typeparam> /// <param name = "dataRow"> </param> // <returns> </returns> public static Func <DataRow, t> ToExpression <T> (this DataRow dataRow) where T: class, new () {if (dataRow = null) throw new ArgumentNullException ("dataRow ", "The current object is null and cannot be converted to an object"); ParameterExpression parameter = E Xpression. parameter (typeof (DataRow), "dr"); List <MemberBinding> binds = new List <MemberBinding> (); for (int I = 0; I <dataRow. itemArray. length; I ++) {String colName = dataRow. table. columns [I]. columnName; PropertyInfo pInfo = typeof (T ). getProperty (colName); if (pInfo = null |! PInfo. canWrite) continue; MethodInfo mInfo = typeof (DataRowExtensions ). getMethod ("Field", new Type [] {typeof (DataRow), typeof (String )}). makeGenericMethod (pInfo. propertyType); MethodCallExpression call = Expression. call (mInfo, parameter, Expression. constant (colName, typeof (String); MemberAssignment bind = Expression. bind (pInfo, call); binds. add (bind);} MemberInitExpression init = Expression. mem BerInit (Expression. new (typeof (T), binds. toArray (); return Expression. lambda <Func <DataRow, T> (init, parameter ). compile ();} # endregion // <summary> // generate a lambda expression // </summary> // <typeparam name = "T"> </typeparam> // <param name = "reader"> </param> // <returns> </returns> public static Func <SqlDataReader, t> ToExpression <T> (this SqlDataReader reader) where T: class, new () {if (reader = null | Reader. IsClosed |! Reader. hasRows) throw new ArgumentException ("reader", "the current object is invalid"); ParameterExpression parameter = Expression. parameter (typeof (SqlDataReader), "reader"); List <MemberBinding> binds = new List <MemberBinding> (); for (int I = 0; I <reader. fieldCount; I ++) {String colName = reader. getName (I); PropertyInfo pInfo = typeof (T ). getProperty (colName); if (pInfo = null |! PInfo. canWrite) continue; MethodInfo mInfo = reader. getType (). getMethod ("GetFieldValue "). makeGenericMethod (pInfo. propertyType); MethodCallExpression call = Expression. call (parameter, mInfo, Expression. constant (I); MemberAssignment bind = Expression. bind (pInfo, call); binds. add (bind);} MemberInitExpression init = Expression. memberInit (Expression. new (typeof (T), binds. toArray (); return Expression. lambda <Func <SqlDataReader, T> (init, parameter ). compile ();}}}

Added the SqlDataReader extension method based on the previous article.

The following code calls

using System;using System.Collections.Generic;using System.Data;using System.Data.Common;using System.Data.SqlClient;using System.Diagnostics;using System.Linq;using System.Reflection;using System.Text;using System.Threading.Tasks;namespace Demo1{ class Program {  static void Main(string[] args)  {   String conString = "Data Source=.; Initial Catalog=master; Integrated Security=true;";   Func<SqlDataReader, Usr> func = null;   List<Usr> usrs = new List<Usr>();   using (SqlDataReader reader = GetReader(conString, "select object_id 'ID',name 'Name' from sys.objects", CommandType.Text, null))   {    while (reader.Read())    {     if (func == null)     {      func = reader.ToExpression<Usr>();     }     Usr usr = func(reader);     usrs.Add(usr);    }   }   usrs.Clear();   Console.ReadKey();  }  public static SqlDataReader GetReader(String conString, String sql, CommandType type, params SqlParameter[] pms)  {   SqlConnection conn = new SqlConnection(conString);   SqlCommand cmd = new SqlCommand(sql, conn);   cmd.CommandType = type;   if (pms != null && pms.Count() > 0)   {    cmd.Parameters.AddRange(pms);   }   conn.Open();   return cmd.ExecuteReader(CommandBehavior.CloseConnection);  } } class Usr {  public Int32 ID { get; set; }  public String Name { get; set; } }}

Currently, only objects returned by SQL Server can be processed. In other databases, the extension method of DbDataReader is intended to be added. However, an error occurs when a lambda expression is dynamically generated.

The solution is recorded.

Related Article

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.