2011-04-19 52 views
0

我有一个数据库,我必须通过odbc连接。如何优化数据表到集合转换的运行时?

数据获取需要应用程序。 2分钟。并且生成的DataTable有350000条记录。

我想把数据表转换成这个对象图。结果集没有主键,主键通过从中获取数据的视图指定。

public class PriceCurve 
{ 
    public PriceCurve(DataTable dt) 
    { 
     this.Id = int.Parse(dt.AsEnumerable().First()["ID"].ToString()); 
     this.Prices = new List<Price>(); 
     GetPrices(dt); 
    } 

    public int Id { get; private set; } 
    public IList<Price> Prices { get; set; } 

    private void GetPrices(DataTable dt) 
    { 
     foreach (DataColumn column in dt.Columns) 
     { 
      switch (this.GetPriceProviderType(column)) // parses ColumnName to Enum 
      { 
       case Price.PriceProvider.A: 
        { 
         this.Prices.Add(new Price(Price.PriceProvider.A, dt.AsEnumerable())); 
        } 

        break; 
       case Price.PriceProvider.B: 
        { 
         this.Prices.Add(new Price(Price.PriceProvider.B, dt.AsEnumerable())); 
        } 

        break; 
      } 
     } 

    public class Price 
    { 
     public enum PriceProvider 
     { 
      A, B 
     } 

     public Price(PriceProvider type, IEnumerable<DataRow> dt) 
     { 
      this.Type = type; 
      this.TradingDates = new List<TradingDate>(); 
      this.GetTradingDates(type, dt); 
     } 

     public IList<TradingDate> TradingDates { get; set; } 
     public PriceProvider Type { get; set; } 

     private void GetTradingDates(PriceProvider type, IEnumerable<DataRow> dt) 
     { 
      var data = dt.Select(column => column["TRADING_DATE"]).Distinct(); 

      foreach (var date in data) 
      { 
       this.TradingDates.Add(new TradingDate(date.ToString(), type, dt)); 
      } 
     } 

     public class TradingDate 
     { 
      public TradingDate(string id, PriceProvider type, IEnumerable<DataRow> dt) 
      { 
       this.Id = id; 
       this.DeliveryPeriodValues = new Dictionary<int, double?>(); 
       this.GetDeliveryPeriodValues(type, dt); 
      } 

      public string Id { get; set; } 
      public IDictionary<int, double?> DeliveryPeriodValues { get; set; } 

      private void GetDeliveryPeriodValues(PriceProvider type, IEnumerable<DataRow> dt) 
      { 

       foreach (var row in dt.Where(column => column["TRADING_DATE"].ToString() == this.Name)) 
       { 
        try 
        { 
         this.DeliveryPeriodValues.Add(
          int.Parse(row["DELIVERY_PERIOD"].ToString()), 
          double.Parse(row[Enum.GetName(typeof(Price.PriceProvider), type)].ToString())); 
        } 
        catch (FormatException e) 
        { 
         this.DeliveryPeriodValues.Add(
          int.Parse(row["DELIVERY_PERIOD"].ToString()), 
          null); 
        } 
       }  
      } 
     } 
    } 

我创建了一个对象,其中包含一个包含两个对象的列表。这两个对象都包含一个包含1000个对象的列表。这1000个对象中的每一个都包含一个包含350对的字典。

它在调试期间崩溃visual studio 2010,由于OutOfMemory失败或需要几分钟(不可接受)执行。

这个问题的最佳解决方法是什么?我是新来的C#和不知道如何优化通过这个巨大的数据或我的对象图循环。任何帮助表示赞赏。

回答

1

它在调试期间崩溃visual studio 2010,由于OutOfMemory失败或需要分钟 (不可接受)执行。

YOu让我发笑。真。

  • 350.000节点在使用.NET的32位机器上具有挑战性。增加一些开销,你已经死了。使用对象,而不是非常内存销毁的adata表。

  • 需要几分钟几乎是你的决定/编程。使用对象列表,而不是数据表。使用分析器。不要让初学者mistakesl IKE:

VAR数据= dt.Select(柱=>柱[ “TRADING_DATE”])个不同的();

没有必要,稍后在代码中处理双打。不同的是昂贵的。描述它。

的foreach(在dt.Where VAR行(列=>柱[ “TRADING_DATE”]。的ToString()== this.Name))

即由名称为350.000行查找,以获取该列的索引,比较了很多tostring。

获得一个分析器,并找出你确切地花费你的时间。获取请摆脱表和使用对象 - 与一系列对象相比,DataTable是一个内存管理器和SLOW。是的,这需要几分钟时间。主要原因:

  • 您的编程。不是一个耻辱。只要学习,立即去做objets/structs。
  • ODBC。花时间去加载数据,特别是当你不处理swhile加载(DataReader),但等待所有加载的数据,并且ODBC不是很快。 350.000行,良好的网络,直接的SQL Server可能是30秒 - 相同的机器少。
+0

因此,我应该基本上采取数据读取器,并直接与reader.GetNames(新对象[])返回的每个对象[]) – mrt181 2011-04-19 20:02:06

+0

不,这是一个数组,而不是adata传输对象。你应该立即将它们转换成真正的物品。你知道,具有变量,属性的类型。 – TomTom 2011-04-20 03:53:23

+0

是的,我听说过这个东西;)。 所以最好的方法就像{var neededCol = reader.GetOrdinal(“TRADING_DATE”); var myObj = new PriceCurve(); while(reader.Read()){myObj.MyProperty = reader.GetValue(neededCol);}} – mrt181 2011-04-20 06:46:32