在C#中使用泛型

时间:2011-03-13 18:58:09

标签: c# generics

我已经开始考虑在C#中使用泛型。作为一个例子,我所做的是我有一个实现泛型方法的抽象类。这些泛型方法将sql查询,连接字符串和Type T作为参数,然后构造数据集,填充对象并将其返回。这样,每个业务对象都不需要有一个方法来用数据填充它或构造它的数据集。我们需要做的就是传递类型,sql查询和连接字符串,这些方法完成其余的工作。我在这里提供代码示例。我只是想与那些可能有更好解决方案的人讨论。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using MWTWorkUnitMgmtLib.Business;
using System.Collections.ObjectModel;
using System.Reflection;

namespace MWTWorkUnitMgmtLib.TableGateway
{
    public abstract class TableGateway
    {
        public TableGateway()
        {

        }

        protected abstract string GetConnection();
        protected abstract string GetTableName();

        public DataSet GetDataSetFromSql(string connectionString, string sql)
        {
            DataSet ds = null;
            using (SqlConnection connection = new SqlConnection(connectionString))
            using (SqlCommand command = connection.CreateCommand())
            {
                command.CommandText = sql;
                connection.Open();
                using (ds = new DataSet())
                using (SqlDataAdapter adapter = new SqlDataAdapter(command))
                {
                    adapter.Fill(ds);
                }
            }
            return ds;
        }

        public static bool ContainsColumnName(DataRow dr, string columnName)
        {
            return dr.Table.Columns.Contains(columnName); 
        }

        public DataTable GetDataTable(string connString, string sql)
        {
            DataSet ds = GetDataSetFromSql(connString, sql);
            DataTable dt = null;
            if (ds != null)
            {
                if (ds.Tables.Count > 0)
                {
                    dt = ds.Tables[0];
                }
            }
            return dt; 
        }

        public T Construct<T>(DataRow dr, T t) where T : class, new()
        {
            Type t1 = t.GetType();
            PropertyInfo[] properties = t1.GetProperties();

            foreach (PropertyInfo property in properties)
            {
                if (ContainsColumnName(dr, property.Name) && (dr[property.Name] != null))
                    property.SetValue(t, dr[property.Name], null); 
            }

            return t; 
        }

        public T GetByID<T>(string connString, string sql, T t) where T : class, new()
        {
            DataTable dt = GetDataTable(connString, sql);
            DataRow dr = dt.Rows[0];
            return Construct(dr, t); 
        }

        public List<T> GetAll<T>(string connString, string sql, T t) where T : class, new()
        {
            List<T> collection = new List<T>();
            DataTable dt = GetDataTable(connString, sql);
            foreach (DataRow dr in dt.Rows)
                collection.Add(Construct(dr, t));

            return collection; 
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您可以通过生成和缓存代理来设置属性来改进性能:

public static class Utils
{
        public static Action<T, object> MethodDelegateFor<T>(MethodInfo method)
        {
            var parameter = method.GetParameters().Single();
            var instance = Expression.Parameter(typeof(T), "instance");
            var argument = Expression.Parameter(typeof(object), "argument");
            var methodCall = Expression.Call(
                instance,
                method,
                Expression.Convert(argument, parameter.ParameterType)
                );
            return Expression.Lambda<Action<T, object>>(
                methodCall,
                instance, argument
                ).Compile();
        }

        public static Action<T, object> PropertySetterFor<T>(PropertyInfo property)
        {
            return MethodDelegateFor<T>(property.GetSetMethod());
        }
}

用法:

var propSetter = Utils.PropertySetterFor<T>(yourPropInfo);
propSetter(newInstance, theValue);

答案 1 :(得分:0)

我相信,使用工作单元模式和存储库模式会更强大,但会修改为通用示例。

然后你可以构建一个功能齐全的CRUD,使用Polymorphism进行“特殊”的事情,你需要专业化。

还会使用实体框架切换旧的SQL命令。会大大减轻你的工作量。

这就是我要做的。