C# 数据表到列表<对象>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/709035/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 14:17:00  来源:igfitidea点击:

DataTable to List<object>

c#dataset

提问by Coppermill

How do I take a DataTable and convert it to a List?

如何获取数据表并将其转换为列表?

I've included some code below in both C# and VB.NET, the issue with both of these is that we create a new object to return the data, which is very costly. I need to return a reference to the object.

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

The DataSetNoteProcsTableAdapters.up_GetNoteRow object does implement the INote interface.

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

I am using ADO.NET, along with .NET 3.5

我正在使用 ADO.NET 和 .NET 3.5

c# code

代码

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 Code

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

采纳答案by Guffa

No, creating a list is not costly. Compared to creating the data table and fetching the data from the database, it's very cheap.

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

You can make it even cheaper by creating the list after populating the table, so that you can set the initial capacity to the number of rows that you will put in it:

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

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

回答by Craig

If the properties of the list match the field names in the datatable you should be able to create some kind of generic reflection routine.

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

回答by Rune Grimstad

Do you want to reference the rows of the table? In that case you should use the DataTable.Rows property.

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

Try this:

尝试这个:

notes.AddRange(table.Rows);

If the table rows implement INote then this should work.

如果表行实现 INote 那么这应该可以工作。

Alternatively you could do as you did above:

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

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

回答by cerhart

Why not pass the DataTable into to the function instead of instantiating it? That would simply contain a reference.

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

That's way too simple an answer too be worthwhile to you I'm sure, but I don't see how it doesn't solve your problem.

我敢肯定,这个答案太简单了,对您来说也不值得,但我不明白它如何不能解决您的问题。

回答by Guffa

No sure if this is what your looking for but you could try something like this.

不确定这是否是您想要的,但您可以尝试这样的操作。

    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;
    }
}

This is what I have done so hope this helps. Not sure if it is the right way to do it but it works for what we needed it for.

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

回答by Junior Mayhé

I have another approach that might be worth taking a look at. It's a helper method. Create a custom class file named CollectionHelper:

我有另一种方法可能值得一看。这是一个辅助方法。创建一个名为 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);
    }

Imagine you want to get a list of customers. Now you'll have the following caller:

想象一下,您想要获取客户列表。现在您将拥有以下调用者:

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

The attributes you have in your DataTable must match your Customer class (fields like Name, Address, Telephone).

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

I hope it helps!

我希望它有帮助!

For who are willing to know why to use lists instead of DataTables: link text

谁愿意知道为什么使用列表而不是数据表:链接文本

The full sample:

完整样本:

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

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

回答by Vijay Bansal

This is one simple way to do it. Say you have a history of events to pull from the database and you've a class like this:

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

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

Then from database you pull event history records in a dataset:

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

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

And then from the dataset in to a List of EventHistRecord:

然后从数据集中到一个 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();