我正在创建一个通用应用程序,以从不同的SQL Server表中获取所有数据。
我有一个将SqlDataReader
转换为列表的通用函数:
public static List<T> MapToList<T>(this SqlDataReader dr) where T : new()
{
List<T> RetVal = null;
var Entity = typeof(T);
var PropDict = new Dictionary<string, PropertyInfo>();
try
{
if (dr != null && dr.HasRows)
{
RetVal = new List<T>();
var Props = Entity.GetProperties(BindingFlags.Instance | BindingFlags.Public);
PropDict = Props.ToDictionary(p => p.Name.ToUpper(), p => p);
while (dr.Read())
{
T newObject = new T();
for (int Index = 0; Index < dr.FieldCount; Index++)
{
if (PropDict.ContainsKey(dr.GetName(Index).ToUpper()))
{
var Info = PropDict[dr.GetName(Index).ToUpper()];
if ((Info != null) && Info.CanWrite)
{
var Val = dr.GetValue(Index);
Info.SetValue(newObject, (Val == DBNull.Value) ? null : Val, null);
}
}
}
RetVal.Add(newObject);
}
}
}
catch (Exception)
{
throw;
}
return RetVal;
}
现在假设我有此类用于数据:
public partial class User
{
public int Id { get; set; }
public string Name { get; set; }
}
我可以从表中获取数据,如下所示:
const string GetAreasQuery = "select id, name from dbo.user";
SqlDataReader dr = DoQueryToDB(GetAreasQuery);
List<User> userList = dr.MapToList<User>();
现在,我有n个不同的类,例如User
(Classroom
等),我不想为我拥有的每个类编写上面的代码。我想创建一个通用的GetData
来检索这些信息:
public List<T> GetData<T> (string Query_)
{
SqlDataReader dr = DataReader(Query_);
List<T> data = new List<T>();
data = dr.MapToList<T>();
return data;
}
其中T
可以是User
,Classroom
等...
我尝试了此解决方案,但始终必须指定类型:
public object GetData(string Query_, Type type)
{
SqlDataReader dr = DataReader(Query_);
if (type == typeof(User))
{
List<User> data = new List<User>();
data = dr.MapToList<User>();
return data;
}
else if (..)
{}
return null;
}
我正在尝试不同的可能性,但是我总是在GetData<T>
函数中遇到错误。更准确地说,像MapToList<T>
中那样:T应该是非抽象类型或没有参数的公共构造函数。
答案 0 :(得分:2)
您应该在GetData方法中添加一个约束,以实现与MapToList中相同的约束级别,该约束级别要求T具有空的构造函数
public List<T> GetData<T>(string Query_) where T : new()
{
SqlDataReader dr = DataReader(Query_);
return dr.MapToList<T>();
}