ListHelper

来源:互联网 发布:linux系统改ip地址 编辑:程序博客网 时间:2024/06/16 04:09

using System;using System.Reflection;using System.Data.SqlClient;using System.Linq;using System.Linq.Expressions;using System.Collections.Generic;namespace xxxxxxxxxxxx{    public class ListHelper<T>    {        public List<T> CreateList(SqlDataReader reader)        {            Func<SqlDataReader, T> readRow = this.GetReader(reader);            var results = new List<T>();            while (reader.Read())                results.Add(readRow(reader));            return results;        }        public List<T> SortList(List<T> listToSort, string propertyName, bool ascending)        {            // verify that the propertyName is valid            var propertyNames = typeof(T).GetProperties().ToList().Select(p => p.Name).ToList();            if (!propertyNames.Contains(propertyName))                throw new ArgumentOutOfRangeException("There is no property named: " + propertyName);            var paramExpression = Expression.Parameter(typeof(T), "item");            var propertyExpression = Expression.Convert(Expression.Property(paramExpression, propertyName), typeof(object));            var lambdaExpression = Expression.Lambda<Func<T, object>>(propertyExpression, paramExpression);            if (ascending)                return listToSort.AsQueryable().OrderBy(lambdaExpression).ToList();            else                return listToSort.AsQueryable().OrderByDescending(lambdaExpression).ToList();        }        private Func<SqlDataReader, T> GetReader(SqlDataReader reader)        {            Delegate resDelegate;            List<string> readerColumns = new List<string>();            for (int index = 0; index < reader.FieldCount; index++)                readerColumns.Add(reader.GetName(index));            // a list of LINQ expressions that will be used for each data row            var statements = new List<Expression>();            // get the indexer property of SqlDataReader            var indexerProperty = typeof(SqlDataReader).GetProperty("Item", new[] { typeof(string) });            // Parameter expression to create instance of object            ParameterExpression instanceParam = Expression.Variable(typeof(T));            ParameterExpression readerParam = Expression.Parameter(typeof(SqlDataReader));            // create and assign new instance of variable            BinaryExpression createInstance = Expression.Assign(instanceParam, Expression.New(typeof(T)));            statements.Add(createInstance);            // loop through each of the properties in T to determine how to populate the new instance properties            var properties = typeof(T).GetProperties();            var columnNames = this.GetColumnNames(properties);            foreach (var property in properties)            {                string columnName = columnNames[property.Name];                //string columnName = property.Name;                if (readerColumns.Contains(columnName))                {                    // get the instance.Property                    MemberExpression setProperty = Expression.Property(instanceParam, property);                    // the database column name will be what is in the columnNames list -- defaults to the property name                    IndexExpression readValue = Expression.MakeIndex(readerParam, indexerProperty, new[] { Expression.Constant(columnName) });                    ConstantExpression nullValue = Expression.Constant(DBNull.Value, typeof(System.DBNull));                    BinaryExpression valueNotNull = Expression.NotEqual(readValue, nullValue);                    if (property.PropertyType.Name.ToLower().Equals("string"))                    {                        ConditionalExpression assignProperty = Expression.IfThenElse(                            valueNotNull,                            Expression.Assign(setProperty, Expression.Convert(readValue, property.PropertyType)),                            Expression.Assign(setProperty, Expression.Constant("", typeof(System.String)))                        );                        statements.Add(assignProperty);                    }                    else                    {                        ConditionalExpression assignProperty = Expression.IfThen(                            valueNotNull,                            Expression.Assign(setProperty, Expression.Convert(readValue, property.PropertyType))                        );                        statements.Add(assignProperty);                    }                }            }            var returnStatement = instanceParam;            statements.Add(returnStatement);            var body = Expression.Block(instanceParam.Type, new[] { instanceParam }, statements.ToArray());            var lambda = Expression.Lambda<Func<SqlDataReader, T>>(body, readerParam);            resDelegate = lambda.Compile();            return (Func<SqlDataReader, T>)resDelegate;        }        private Dictionary<string, string> GetColumnNames(PropertyInfo[] properties)        {            var columnNames = new Dictionary<string, string>();            foreach (var property in properties)            {                string columnName = property.Name;                var attributes = property.GetCustomAttributes(typeof(Attributes.DatabaseProperty), true);                if (attributes.Length > 0)                    columnName = ((Attributes.DatabaseProperty)attributes[0]).ColumnName;                columnNames.Add(property.Name, columnName);            }            return columnNames;        }    }}

[AttributeUsage(AttributeTargets.Property)]   public class DatabaseProperty : Attribute   {      private string _columnName;      public string ColumnName      {         get { return _columnName; }         set { _columnName = value; }      }   }

[Serializable]    public class Employee    {        public int EmployeeID { get; set; }        public string LastName { get; set; }        public string FirstName { get; set; }        public string Title { get; set; }        public DateTime? BirthDate { get; set; }        public DateTime? HireDate { get; set; }        public string City { get; set; }        public string Notes { get; set; }        public byte[] Photo { get; set; }    }    [Serializable]    public class Customer    {        public int CustomerID { get; set; }        [DatabaseProperty(ColumnName = "CompanyName")]        public string Name { get; set; }        public string ContactName { get; set; }        public string ContactTitle { get; set; }        public string Address { get; set; }        public string City { get; set; }        public string Region { get; set; }        public string PostalCode { get; set; }        public string Country { get; set; }        public string Phone { get; set; }        public string Fax { get; set; }    }

使用demo:

using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["northwind"].ConnectionString)){    conn.Open();    var query = "select * from Employees order by LastName, FirstName";    var cmd = new SqlCommand(query, conn);    using (var reader = cmd.ExecuteReader())    {        this.EmployeeList = new GenericPopulator.ListHelper<Models.Employee>().CreateList(reader);        this.EmployeeList = new GenericPopulator.ListHelper<Models.Employee>().SortList(this.EmployeeList, "LastName", true);        rptEmployees.DataSource = this.EmployeeList;        rptEmployees.DataBind();        gvEmployees.DataSource = this.EmployeeList;        gvEmployees.DataBind();             reader.Close();    }    conn.Close();}





0 0
原创粉丝点击