SORU
19 ŞUBAT 2009, PERŞEMBE


Genel Liste DataTable/Sayısız dönüştürmek?

Farklı Jenerik Listeler döndüren birkaç yöntem var.

Var .bir datatable içine herhangi bir liste dönüştürmek için ne olursa olsun herhangi bir sınıf statik bir yöntem net mi? Hayal edebileceğim tek şey Yansıma bunu yapmak için kullanın.

Eğer bu VARSA:

List<Whatever> whatever = new List<Whatever>();

Bu kod tabiki işe yaramaz, ama olasılığı olsun istiyorum:

DataTable dt = (DataTable) whatever;

CEVAP
19 ŞUBAT 2009, PERŞEMBE


İşte güzel 2013 güncellemesi NuGet FastMember kullanarak:

IEnumerable<SomeType> data = ...
DataTable table = new DataTable();
using(var reader = ObjectReader.Create(data)) {
    table.Load(reader);
}

Bu maksimum performans için FastMember meta-programlama API kullanır. Eğer belirli üyeleri ile sınırlamak istiyorsanız (ya da düzeni sağlamak), o zaman siz de bunu yapabilirsiniz:

IEnumerable<SomeType> data = ...
DataTable table = new DataTable();
using(var reader = ObjectReader.Create(data, "Id", "Name", "Description")) {
    table.Load(reader);
}

EditörünDis/bahis ATI:FastMember Marc Gravell bir proje. Altın ve tam karasinek!


Evet, bu çok this bir tam tersidir; yansıma - ya da eğer daha hızlı ihtiyacınız varsa, HyperDescriptor 3.5 2.0, belki de Expression yeterli olurdu. Aslında HyperDescriptor yeterli daha fazla olmalıdır.

Örneğin:

// remove "this" if not on C# 3.0 / .NET 3.5
public static DataTable ToDataTable<T>(this IList<T> data)
{
    PropertyDescriptorCollection props =
        TypeDescriptor.GetProperties(typeof(T));
    DataTable table = new DataTable();
    for(int i = 0 ; i < props.Count ; i  )
    {
        PropertyDescriptor prop = props[i];
        table.Columns.Add(prop.Name, prop.PropertyType);
    }
    object[] values = new object[props.Count];
    foreach (T item in data)
    {
        for (int i = 0; i < values.Length; i  )
        {
            values[i] = props[i].GetValue(item);
        }
        table.Rows.Add(values);
    }
    return table;        
}

Bir satır ile artık bu çok daha hızlı yansımasından (nesne tipi T HyperDescriptor etkinleştirerek) birçok yapabilirsiniz.


re performans sorgu Düzenle; burada sonuçları ile test teçhizat:

Vanilla 27179
Hyper   6997

Darboğaz-üye DataTable performans değişti sanırım... ... kadar bu konuda geliştirmek şüpheliyim...

kod:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
public class MyData
{
    public int A { get; set; }
    public string B { get; set; }
    public DateTime C { get; set; }
    public decimal D { get; set; }
    public string E { get; set; }
    public int F { get; set; }
}

static class Program
{
    static void RunTest(List<MyData> data, string caption)
    {
        GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
        GC.WaitForPendingFinalizers();
        GC.WaitForFullGCComplete();
        Stopwatch watch = Stopwatch.StartNew();
        for (int i = 0; i < 500; i  )
        {
            data.ToDataTable();
        }
        watch.Stop();
        Console.WriteLine(caption   "\t"   watch.ElapsedMilliseconds);
    }
    static void Main()
    {
        List<MyData> foos = new List<MyData>();
        for (int i = 0 ; i < 5000 ; i   ){
            foos.Add(new MyData
            { // just gibberish...
                A = i,
                B = i.ToString(),
                C = DateTime.Now.AddSeconds(i),
                D = i,
                E = "hello",
                F = i * 2
            });
        }
        RunTest(foos, "Vanilla");
        Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(
            typeof(MyData));
        RunTest(foos, "Hyper");
        Console.ReadLine(); // return to exit        
    }
}

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • alex maybury

    alex maybury

    20 Aralık 2007
  • bethliebert

    bethliebert

    23 EKİM 2008
  • THELIFEOFPRICE

    THELIFEOFPRI

    16 Mart 2011