DataTable to List <object> </object>

时间:2009-04-02 09:45:09

标签: c# dataset

如何获取DataTable并将其转换为List?

我在C#和VB.NET中都包含了一些代码,这两个问题都是我们创建一个新对象来返回数据,这是非常昂贵的。我需要返回对象的引用。

DataSetNoteProcsTableAdapters.up_GetNoteRow对象确实实现了INote接口。

我正在使用ADO.NET以及.NET 3.5

c#c​​ode

public static IList<INote> GetNotes() 
{ 
    DataSetNoteProcsTableAdapters.up_GetNoteTableAdapter adapter =
        new DataSetNoteProcsTableAdapters.up_GetNoteTableAdapter(); 
    DataSetNoteProcs.up_GetNoteDataTable table =
        new DataSetNoteProcs.up_GetNoteDataTable(); 

    IList<INote> notes = new List<INote>(); 

    adapter.Connection = DataAccess.ConnectionSettings.Connection; 
    adapter.Fill(table); 

    foreach (DataSetNoteProcs.up_GetNoteRow t in table) { 
        notes.Add((INote)t); 
    } 

    return notes;
} 

VB.NET代码

Public Shared Function GetNotes() As IList(Of INote)
    Dim adapter As New DataSetNoteProcsTableAdapters.up_GetNoteTableAdapter
    Dim table As New DataSetNoteProcs.up_GetNoteDataTable

    Dim notes As IList(Of INote) = New List(Of INote)

    adapter.Connection = DataAccess.ConnectionSettings.Connection
    adapter.Fill(table)

    For Each t As DataSetNoteProcs.up_GetNoteRow In table
        notes.Add(CType(t, INote))
    Next

    Return notes
End Function

7 个答案:

答案 0 :(得分:6)

我有另一种方法可能值得一看。 这是一种帮助方法。创建名为CollectionHelper的自定义类文件:

    public static IList<T> ConvertTo<T>(DataTable table)
    {
        if (table == null)
            return null;

        List<DataRow> rows = new List<DataRow>();

        foreach (DataRow row in table.Rows)
            rows.Add(row);

        return ConvertTo<T>(rows);
    }

想象一下,您想获得一份客户名单。现在您将拥有以下来电者:

List<Customer> myList = (List<Customer>)CollectionHelper.ConvertTo<Customer>(table);

您的DataTable中的属性必须与您的Customer类(名称,地址,电话等字段)匹配。

我希望它有所帮助!

谁愿意知道为什么要使用列表而不是DataTables:link text

完整样本:

http://lozanotek.com/blog/archive/2007/05/09/Converting_Custom_Collections_To_and_From_DataTable.aspx

答案 1 :(得分:2)

不,创建列表并不昂贵。与创建数据表和从数据库中获取数据相比,它非常便宜。

您可以通过在填充表格后创建列表来使其更便宜,这样您就可以将初始容量设置为您将放入其中的行数:

IList<INote> notes = new List<INote>(table.Rows.Count);

答案 2 :(得分:1)

为什么不将DataTable传递给函数而不是实例化它?这只会包含一个参考。

这太简单了,对你来说也是值得的,我敢肯定,但我不知道它是如何解决你的问题的。

答案 3 :(得分:1)

不确定这是否是你想要的,但你可以尝试这样的事情。

    public class Category
{
    private int _Id;
    public int Id
    {
        get { return _Id; }
        set { _Id = value; }
    }

    private string _Name = null;
    public string Name
    {
        get { return _Name; }
        set { _Name = value; }
    }

    public Category()
    {}

    public static List<Category> GetCategories()
    {
        List<Category> currentCategories = new List<Category>();

        DbCommand comm = GenericDataAccess.CreateTextCommand();
        comm.CommandText = "SELECT Id, Name FROM Categories Order By Name";
        DataTable table = GenericDataAccess.ExecuteSelectCommand(comm);

        foreach (DataRow row in table.Rows)
        {
            Category cat = new Category();
            cat.Id = int.Parse(row["Id"].ToString());
            cat.Name = row["Name"].ToString();
            currentCategories.Add(cat);
        }
        return currentCategories;
    }
}

这就是我所做的,所以希望这会有所帮助。不确定这是否是正确的方法,但它适用于我们所需要的。

答案 4 :(得分:0)

您想引用表格的行吗?在这种情况下,您应该使用DataTable.Rows属性。

试试这个:

notes.AddRange(table.Rows);

如果表行实现了INote,那么这应该可行。

或者你可以像上面那样做:

foreach (INote note in table.Rows)
{
  notes.Add(note)
}

答案 5 :(得分:0)

这是一种简单的方法。假设您有要从数据库中提取事件的历史记录,并且您有一个像这样的类:

public class EventHistRecord
{
    public string EvtDate { get; set; }
    public string EvtType { get; set; }
    public string EvtUser { get; set; }
    public string EvtData { get; set; }
}

然后从数据库中提取事件历史记录到数据集中:

DataSet ds = SqlQueries.getDataSet("select * from EventHist", phoneNum);

然后从数据集中进入EventHistRecord列表:

    List<EventHistoryRecord> lstRecs = ds.Tables[0].AsEnumerable().Select(
dr => new EventHistoryRecord { EvtDate= dr["EvtDate"].ToString(),
                               EvtData = dr["EvtData"].ToString(),
                               EvtType = dr["EvtType"].ToString(),
                               EvtUser = dr["EvtUser"].ToString() 
                              }).ToList();

答案 6 :(得分:-1)

如果列表的属性与数据表中的字段名称匹配,则应该能够创建某种通用的反射例程。