[英]using Generics in C#
我已经开始研究在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;
}
}
}
您可以通过生成和缓存用于设置属性的委托来提高性能:
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);
我相信,将工作单元模式与存储库模式一起使用会更强大,但可以修改为通用示例。
然后,您可以构建功能全面的CRUD,并针对“特殊”事物使用多态性,您需要进行专业化处理。
还将使用实体框架切换旧的SQL命令。 会大大减轻您的工作量。
那就是我会做的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.