如何创建动态IEnumerable

时间:2015-06-05 08:48:29

标签: c# reflection collections

我知道这对你来说是一个简单的问题。但我是c#的初学者。 我想要实现的是创建一个方法,将从我的模型中存储任何类型的对象列表。例如List<Person>

我试图做这样的事情......

public IEnumerable<T> GetObjects<T>()
{
    Type type = typeof(T);

    PropertyInfo[] properties = type.GetProperties();

    foreach (PropertyInfo item in properties)
    {
        // store properties
    }


    List<T> objects = new List<T>();

    using (SqlConnection str = GetSqlConnection)
    {
        // retrieve data from db 
        //then store it to list of objects
    }

    return objects;

}

这将使我能够仅使用此方法检索数据。

编辑:

我已经设法创建此示例代码以从数据库中检索特定的表。

public IEnumerable<ItemBrand> getAllBrand
{
    get
    {
        List<ItemBrand> brands = new List<ItemBrand>();

        using (MySqlConnection strConn = getMySqlConnection())
        {
            string query = "SELECT * FROM tblbrand";
            MySqlCommand cmd = new MySqlCommand(query, strConn);

            strConn.Open();
            MySqlDataReader rd = cmd.ExecuteReader();

            while (rd.Read())
            {
                ItemBrand brand = new ItemBrand();

                brand.brandID = Convert.ToInt32(rd["brandID"]);
                brand.Name = rd["brandName"].ToString();

                brands.Add(brand);
            }

            return brands;
        }
    }
}

目前我的解决方案中有多种方法。我很乐意在您的帮助下删除这些重复的代码。

3 个答案:

答案 0 :(得分:0)

<code> 
  // Create a new type of the entity I want
Type t = typeof(T);

T returnObject = new T();

for (int i = 0; i < dataReader.FieldCount; i++) {
    string colName = string.Empty;
    colName = dataReader.GetName(i);
    // Look for the object's property with the columns name, ignore case
    PropertyInfo pInfo = t.GetProperty(colName.ToLower(), BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

    // did we find the property ?
    if (pInfo != null) {
        if (dataReader.Read()) {
            object val = dataReader[colName];
            // is this a Nullable<> type
            bool IsNullable = (Nullable.GetUnderlyingType(pInfo.PropertyType) != null);
            if (IsNullable) {
                if (val is System.DBNull) {
                    val = null;
                } else {
                    // Convert the db type into the T we have in our Nullable<T> type
                    val = Convert.ChangeType(val, Nullable.GetUnderlyingType(pInfo.PropertyType));
                }
            } else {
                // Convert the db type into the type of the property in our entity
                val = Convert.ChangeType(val, pInfo.PropertyType);
            }
            // Set the value of the property with the value from the db
            pInfo.SetValue(returnObject, val, null);
        }
    }
}

</code> 

答案 1 :(得分:0)

有一个通用方法,如:

public IEnumerable<T> CreateListOfItems(string tableName,
                                        Func<MySqlDataReader, T> itemCreator)
{
    var items = new List<T>();

    using (var strConn = getMySqlConnection())
    {
        string query = "SELECT * FROM " + tableName;
        var cmd = new MySqlCommand(query, strConn);

        strConn.Open();
        var rd = cmd.ExecuteReader();

        while (rd.Read())
        {
            items.Add(itemCreator(rd));
        }
    }
    return items;
}

然后像这样使用:

private ItemBrand CreateItemBrandFromDBData(MySqlDataReader rd)
{
    return new ItemBrand
    {
        BrandID = Convert.ToInt32(rd["brandID"]),
        Name = rd["brandName"].ToString()
    };
}

...

var brands = CreateListOfItems<ItemBrand>(tblbrand, CreateItemBrandFromDBData);

答案 2 :(得分:0)

我编写了一个方法,可以从存储过程中检索结果并将其转换为对象列表。 你唯一需要注意的是: 要映射到的类必须与从数据库发送的列具有相同的列名。

public IEnumerable <T> ExecuteReaderToList<T>(string storedProcedure, IDictionary parameters = null,
              string connectionString = null)
        {
            ICollection list = new List();

var properties = typeof(T).GetProperties(); using (SqlConnection conn = new SqlConnection(connectionString)) { SqlCommand cmd = new SqlCommand(); cmd.CommandText = storedProcedure; cmd.CommandType = CommandType.StoredProcedure; if (parameters != null) { foreach (KeyValuePair<string, object> parameter in parameters) { cmd.Parameters.AddWithValue(parameter.Key, parameter.Value); } } cmd.Connection = conn; conn.Open(); using (SqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { var element = Activator.CreateInstance<T>(); foreach (var f in properties) { var o = reader[f.Name]; if (o.GetType() != typeof(DBNull)) { f.SetValue(element, o, null); } o = null; } list.Add(element); } } conn.Close(); } return list; }