改进插入方法

时间:2010-07-22 13:54:44

标签: linq-to-sql

我写了一个插入方法,它使用linq并循环遍历2个列表,第一个能够达到14k个对象并发送大约8k个对象。

每当我运行此方法时,我总是得到“Transaction Timeout Exception”。你能帮我改进一下吗?

public void InsertNewInventoryGoodsEvents(List<GoodsEvent> eventsList, List<InventoryGoods> goodsList)
{
    InventoryGoodsEvents ige = new InventoryGoodsEvents();
    TransactionScope scope= new TransactionScope();            
    int i = 0;
    const int batchSize = 50; // or even 50    
    foreach (InventoryGoods good in goodsList)
    {
        if (i == 50)
        {
            if (scope != null)
            {
                context.SubmitChanges();
            }
            i = 0;
        }    
        try
        {
             foreach (GoodsEvent g in eventsList)
             {
                 if (g.Gid == good.Gid)
                 {
                     ige = new InventoryGoodsEvents() { EventId = g.Id, InventoryGood = good.Id };    
                     context.InventoryGoodsEvents.InsertOnSubmit(ige);
                 }
             }
         }
         catch (Exception ex)
         {
             ex.ToString();    
         }    
         ++i;
     }
     if (scope != null)
     {    
         context.SubmitChanges();
         scope.Complete();                 
     }
}

3 个答案:

答案 0 :(得分:0)

在同一个交易中完成所有插入是否很重要?如果没有,您是否可以为要插入的每批商品使用新的交易?这应该可以防止交易开放时间过长和超时。

答案 1 :(得分:0)

foreach中的Foreach可以重写为 -

var itsReallyJustAJoin = (from g in GoodEvent
                          join i in InventoryEvent on g.Gid equals i.Gid
                          select new {g.Id, good.Id}).ToList();

然后你可以插入这些你想要的。看起来你现在正在做50批次?如果你愿意的话,你可以继续...这将占用交易范围之外的所有工作,所以如果你的结果不是太大,你可以立刻在那里完成所有工作。

答案 2 :(得分:0)

我在仔细考虑之后重新编写了这个方法,结果如下:

public void InsertNewInventoryGoodsEvents(List<GoodsEvent> eventsList, List<InventoryGoods> goodsList)
        {

            List<InventoryGoodsEvents> mylist = new List<InventoryGoodsEvents>();
            InventoryGoodsEvents ige = new InventoryGoodsEvents();

            foreach (GoodsEvent g in eventsList)
            {
                foreach (InventoryGoods ig in goodsList)
                {
                    if (ig.Gid == g.Gid)
                    {
                        ige = new InventoryGoodsEvents();
                        ige.EventId = g.Id;
                        ige.InventoryGood = ig.Id;
                        mylist.Add(ige);
                    }
                }
            }

            using (var scope = new TransactionScope())
            {
                foreach (InventoryGoodsEvents ip in mylist)
                {
                    context.InventoryGoodsEvents.InsertOnSubmit(ip);
                }

                context.SubmitChanges();
                scope.Complete();
            }
        }

我喜欢MikeM关于简化事情的想法,但我们会看到我会保留哪种方法。