【问题标题】:In C# web forms, how can I load a List from a dataset using generic types?在 C# Web 表单中,如何使用泛型类型从数据集中加载列表?
【发布时间】:2016-09-30 00:35:32
【问题描述】:

我正在尝试将数据集中的内容映射到列表中,但我希望能够将类型传递给函数。我已经有以下代码:

public class WorkOrderAttachment : DatabaseObject
{
    [TableData]
    //public List<int> attachment_id { get; set; }
    public int attachment_id { get; set; }
    [TableData]
    //public List<int> wo_id { get; set; }
    public int wo_id { get; set; }

    public WorkOrderAttachment()
    {

    }

。 . .

public class DatabaseObject
{
    private string _ConnectionString = "";

。 . .

    public static List<T> LoadDataAll<T>(T type, DataSet ds)
    {
        List<T> fillList = new List<T>();
        if (ds.Tables[0].Rows.Count > 0)
        {
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                foreach (var prop in type.GetType().GetProperties())
                {
                    if (prop.GetCustomAttributes(typeof(TableData), false).Length > 0 && ds.Tables[0].Columns.Contains(prop.Name.ToLower()))
                    {
                        if (dr[prop.Name.ToLower()] != DBNull.Value)
                        {
                            prop.SetValue(type, Convert.ChangeType(dr[prop.Name.ToLower()], prop.PropertyType), null);
                        }
                        else
                        {
                            // If we are using a string and the value is null, default to an empty string instead
                            if (prop.PropertyType == typeof(String))
                            {
                                if (dr[prop.Name.ToLower()] == DBNull.Value)
                                {
                                    prop.SetValue(type, "", null);
                                }
                            }
                        }
                    }
                }
                fillList.Add(type);
            }
        }
        return fillList;
    }

。 . .

我是这样使用它的:

return DatabaseObject.LoadDataAll<WorkOrderAttachment>(new WorkOrderAttachment(), ds);

这可行,但假设数据集中的表中有两行。第一次循环时,它会到达 fullList.Add(type) 并将数据放在应有的位置。 "attachment_id = 1, wo_id = 1000"

但是,下一次循环时,它会设置“attachment_id = 2, wo_id = 1000”。一切看起来都很好,但事实并非如此。当我检查填充列表时,我发现了两个条目,但它们都是重复的最后一项“attachment_id = 2,wo_id = 1000”。第一个实例(我知道它已经到位)被覆盖,因为它是通过引用处理的方式,我猜。

(我不想在这种情况下使用实体框架或其他 ORM,但其他​​将数据从数据集中取出到列表中的选项将不胜感激。)

我希望能够指定这样的内容(伪代码):

List<WorkOrderAttachment> Attachments = DatabaseResult();

但是,我还希望它是通用的,这样我就可以将任何类型放入 DatabaseResult 并将我的响应作为已经加载数据的列表。任何有关如何解决此问题或实施更好解决方案的建议表示赞赏。

【问题讨论】:

    标签: c# sql-server generics orm


    【解决方案1】:

    我在 StackOverflow 的另一个问题中找到了答案,即使我的问题与这个不同。答案是一样的:In C#, how to instantiate a passed generic type inside a method?

    public static List<T> LoadDataAll<T>(DataSet ds) where T : new()
    {
    

    。 . .

        foreach (DataRow dr in ds.Tables[0].Rows)
        {
            T type = new T();
            foreach (var prop in type.GetType().GetProperties())
            {
    

    。 . .

    使用 where T : new() 语法,我可以为每一行创建一个新类型,并将其传递给返回的 fillList。我对这个方法的使用如下:

    return DatabaseObject.LoadDataAll<WorkOrderAttachment>(ds);
    

    返回的结果是一个WorkOrderAttachment List,我只是传入数据集。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 2019-07-01
      • 1970-01-01
      相关资源
      最近更新 更多