从SqlDataReader获取数据的通用函数

时间:2018-12-21 14:19:40

标签: c# uwp

我正在创建一个通用应用程序,以从不同的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个不同的类,例如UserClassroom等),我不想为我拥有的每个类编写上面的代码。我想创建一个通用的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可以是UserClassroom等...

我尝试了此解决方案,但始终必须指定类型:

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应该是非抽象类型或没有参数的公共构造函数。

1 个答案:

答案 0 :(得分:2)

您应该在GetData方法中添加一个约束,以实现与MapToList中相同的约束级别,该约束级别要求T具有空的构造函数

public List<T> GetData<T>(string Query_) where T : new()
       {
           SqlDataReader dr = DataReader(Query_);
           return  dr.MapToList<T>();

       }