【问题标题】:Is there a way to store data from a DataReader directly into a List<class> [duplicate]有没有办法将 DataReader 中的数据直接存储到 List<class> [重复]
【发布时间】:2015-04-22 17:57:24
【问题描述】:

我正在从 SqlCommand 创建一个数据读取器,我目前将此信息存储在一个具有以下内容的类中

    private object PopulateObjectWithFields(SqlDataReader read, Type className)
    {
        var gd = Activator.CreateInstance(className);
        for (int i = 0; i < read.FieldCount; i++)
        {
            var type = gd.GetType();

            var fi = type.GetField(read.GetName(i));
            if (fi != null)
            {
                if (!Convert.IsDBNull(read[i]))
                {
                    try
                    {
                        fi.SetValue(gd, read[i]);
                    }
                    catch
                    {
                        throw new Exception(string.Format("Unable to set {0}. Class type {1}. DB Type {2}", read.GetName(i), fi.FieldType.Name, read[i].GetType().Name));
                    }
                }
            }
            else
            {
                var pi = type.GetProperty(read.GetName(i));
                if (pi != null)
                {
                    if (!Convert.IsDBNull(read[i]))
                    {
                        try
                        {
                            pi.SetValue(gd, read[i]);
                        }
                        catch
                        {
                            throw new Exception(string.Format("Unable to set {0}. Class type {1}. DB Type {2}", read.GetName(i), fi.FieldType.Name, read[i].GetType().Name));
                        }
                    }
                }
            }
        }
        return gd;
    }

这非常有效。我现在想把它放在List&lt;class&gt; 中,但我似乎无法正确地动态创建List&lt;class&gt;

有人可以帮我解决语法吗?

var MyList = List<MyClass> //This should be dynamically created

using(var reader = cmd.ExecuteReader())
{
      while (reader.Read())
      {
           MyList.Add(PopulateObjectWithFields(read, MyClass));
      }
}

让我澄清一下 我不知道阅读器中将包含哪些列,也不知道要传入什么类。我有一个通用方法,只要列名就需要将任何阅读器填充到任何类匹配类中字段的属性

【问题讨论】:

  • 你能把它变成一个通用方法,而不是把Type作为参数传入吗?
  • 我也有这样的,我用var gdtype = Assembly.GetExecutingAssembly().GetTypes().First(t =&gt; t.Name == className);从字符串中获取类型,所以没关系
  • 伙计们,我需要一种创建 LIST 的通用方法。不映射或转换任何东西。我想要一种动态的方式来创建List&lt;T&gt;
  • 另请注意,您的解决方案可以提高性能 - 您使用反射来获取每一行的属性列表;您可以预先准备反射属性列表并重用映射。

标签: c# reflection


【解决方案1】:

你应该使用泛型:

private T PopulateObjectWithFields<T>(SqlDataReader read) where T : new()

你的方法的实现保持不变,除了你使用T而不是MyClass,并且你可以使用构造函数直接实例化类型:

var gd = new T();

从那里,您可以轻松地将对象存储在列表中:

var MyList = List<MyClass> //This should be dynamically created

using(var reader = cmd.ExecuteReader())
{
      while (reader.Read())
      {
           MyList.Add(PopulateObjectWithFields<MyClass>(read);
      }
}

【讨论】:

  • 好的,虽然这是一个很好的答案,但这不是我想要的。我想动态创建List&lt;MyClass&gt;,所以我想得到一个 List 而不指定类型。 PopulateObjectWithFields 虽然没有你的那么整洁,但目前运行良好
  • @Jaques 你为什么需要那个?泛型是要走的路。
  • @Jaques 哦,我想我现在明白了。您如何首先从字符串中获得“MyClass”?如果是这样,那么确实泛型并不能解决您的问题。但是,您是否需要一个强类型列表,因为您首先没有静态类型信息?很难用您显示的代码来判断,但也许 List&lt;object&gt; 足以满足您的用例
  • 我使用var gdtype = Assembly.GetExecutingAssembly().GetTypes().First(t =&gt; t.Name == className); 从字符串中获取类。我试过 List 但它给了我很多问题,特别是当我尝试使用组合框或其他东西中的值时
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-28
  • 2020-01-18
  • 1970-01-01
  • 2020-02-23
  • 1970-01-01
  • 1970-01-01
  • 2019-06-05
相关资源
最近更新 更多