Linq to sql 改进方法性能

Linq to sql 改进方法性能,linq-to-sql,Linq To Sql,我编写了以下方法,该方法接收列表并根据特定条件更新数据库: public void UpdateInventoryGoods(List<InventoryGoods> list, int id) { int index = 0; var query = from inventoryGoods in context.InventoryGoods where invento

我编写了以下方法,该方法接收列表并根据特定条件更新数据库:

 public void UpdateInventoryGoods(List<InventoryGoods> list, int id)
        {
            int index = 0;

            var query = from inventoryGoods in context.InventoryGoods
                        where inventoryGoods.ParentId == id
                        select inventoryGoods;

            List<InventoryGoods> goodsList = query.ToList();

            using (var scope = new TransactionScope())
            {
                foreach (InventoryGoods i in list)
                {
                    foreach (InventoryGoods e in goodsList)
                    {
                        if (index == 30)
                        {
                            index = 0;
                            context.SubmitChanges();
                        }

                        if (e.Gid == i.Gid && !getEventId(e.Id).HasValue && !e.ActionOn.HasValue)
                        {
                            e.Action = i.Action;

                        }
                        else if ((e.Gid == i.Gid && getEventId(e.Id).HasValue) && (e.Action != i.Action || i.ActionOn == DateTime.MinValue))
                        {
                            e.Action = i.Action;
                            e.ActionOn = null;

                            var allEvents = from invent in context.InventoryGoodsEvents
                                            where invent.InventoryGood == e.Id
                                            select invent;

                            List<InventoryGoodsEvents> inventoryGoodsEventsList = allEvents.ToList();

                            var events = from g in context.GoodsEvent                                         
                                         select g;

                            List<GoodsEvent> goodsEventList = events.ToList();

                            foreach (InventoryGoodsEvents goodsEvent in inventoryGoodsEventsList)
                            {
                                context.InventoryGoodsEvents.DeleteOnSubmit(goodsEvent);

                                foreach (GoodsEvent ge in goodsEventList)
                                {
                                    if (ge.Id == goodsEvent.EventId)
                                    {
                                        ge.IsDeleted = true;
                                        ge.DeletedOn = DateTime.Now;
                                        ge.DeletedBy = System.Web.HttpContext.Current.User.Identity.Name;
                                    }
                                }                                
                            }




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

        }

        public int? getEventId(int InventoryGood)
        {


            var InventoryGoodsEvents = from i in context.InventoryGoodsEvents
                                       where i.InventoryGood == InventoryGood
                                       select i;

            List<InventoryGoodsEvents> lst = InventoryGoodsEvents.ToList();

            if (lst.Count() > 0)
            {
                return lst[0].EventId;
            }
            else
            {
                return null;
            }
        }
public void UpdateInventoryGoods(列表,int-id)
{
int指数=0;
var query=来自context.inventoryGoods中的inventoryGoods
其中inventoryGoods.ParentId==id
选择库存商品;
List goodsList=query.ToList();
使用(var scope=new TransactionScope())
{
foreach(清单中的库存货物i)
{
foreach(货物清单中的库存货物e)
{
如果(指数=30)
{
指数=0;
context.SubmitChanges();
}
if(e.Gid==i.Gid&&!getEventId(e.Id).HasValue&&!e.ActionOn.HasValue)
{
e、 行动=i.行动;
}
else if((e.Gid==i.Gid&&getEventId(e.Id.HasValue)&&(e.Action!=i.Action | | i.ActionOn==DateTime.MinValue))
{
e、 行动=i.行动;
e、 ActionOn=null;
var allEvents=来自上下文中的invent.InventoryGoodsEvents
其中invent.InventoryGood==e.Id
选择发明;
List inventoryGoodsEventsList=allEvents.ToList();
var events=来自context.GoodsEvent中的g
选择g;
List goodsEventList=events.ToList();
foreach(库存商品清单中的库存商品清单)
{
context.InventoryGoodsEvents.DeleteOnSubmit(goodsEvent);
foreach(GoodsEvent列表中的GoodsEvent ge)
{
if(ge.Id==goodsEvent.EventId)
{
ge.IsDeleted=true;
ge.DeletedOn=DateTime.Now;
ge.DeletedBy=System.Web.HttpContext.Current.User.Identity.Name;
}
}                                
}
}
++指数;
}
}
context.SubmitChanges();
scope.Complete();
}
}
公共整数?getEventId(int InventoryGood)
{
var InventoryGoodsEvents=来自context.InventoryGoodsEvents中的i
其中i.InventoryGood==InventoryGood
选择i;
List lst=InventoryGoodsEvents.ToList();
如果(lst.Count()>0)
{
返回lst[0].EventId;
}
其他的
{
返回null;
}
}
虽然这种方法对大约500或1000个对象很有效,但当我向它提供8000个或更多对象时,它会变得太慢或最终超时。
那么,我在哪里可以稍微提高它的性能呢?

我不是Linq专家,但我认为您可能可以通过以下方式改进
getEventId
(应该是大写字母首字母btw)

public int? GetEventId(int inventoryGood)
{
    var firstInventoryGoodsEvent = context.InventoryGoodsEvents
                  .Where(i => i.InventoryGood == inventoryGood)
                  .FirstOrDefault();

    // ...etc
}
使用
FirstOrDefault()
意味着如果找到匹配的元素,就不会处理整个列表

可能还有其他的优化方法,但是很难理解你在做什么。例如:

 foreach (InventoryGoods i in list)
 {
     foreach (InventoryGoods e in goodsList)
     {
     }
 }
i
e
在这里没有什么意义。您可能很清楚它们的意思,但对于以前从未见过您的代码的人来说,它们并不是很具有描述性。类似地,
list
也不是列表的最佳名称。什么清单?变量名应该描述它的用途

编辑:

我不知道还有什么。您似乎在一些地方使用了
ToList()。我不知道这会对表现产生什么影响,但比我聪明的人可能会告诉你

您还可以尝试在循环之外提升一些值,例如:

foreach (foo)
{
    foreach (bar)
    {
        DeletedOn = DateTime.Now;
        DeletedBy = System.Web.HttpContext.Current.User.Identity.Name;
    }
}
可以重写为

var deletedOn = DateTime.Now;
var deletedBy = System.Web.HttpContext.Current.User.Identity.Name;

foreach (foo)
{
    foreach (bar)
    {
        DeletedOn = deletedOn;
        DeletedBy = deletedBy;
    }
}

再说一次,我不确定这会有多大的不同,如果有的话,你需要对它进行测试,看看。

它不是一批30个,而是一批1个

有一个查询没有条件,所以它会加载整个表。这是你的意图吗


getEventId(e.Id)返回一个一致的值。不要调用它两次(每个循环)。

不要在循环中调用数据库

尝试将查询移出循环,如下所示:

 public void UpdateInventoryGoods(List<InventoryGoods> list, int id)
 {
     int index = 0;

     var query = from inventoryGoods in context.InventoryGoods
                 where inventoryGoods.ParentId == id
                 select inventoryGoods;

     List<InventoryGoods> goodsList = query.ToList();

     using (var scope = new TransactionScope())
     {
         var allEvents = from invent in context.InventoryGoodsEvents
                         where goodsList.Contains(invent.InventoryGood)
                         select invent;

         List<InventoryGoodsEvents> inventoryGoodsEventsList = allEvents.ToList();

         var events = from g in context.GoodsEvent
                      select g;

         List<GoodsEvent> goodsEventList = events.ToList();

         foreach (InventoryGoods i in list)
         {
             foreach (InventoryGoods e in goodsList)
             {
                 if (index == 30)
                 {
                     index = 0;
                     context.SubmitChanges();
                 }

                 var eventId = getEventId(e.Id);
                 if (e.Gid == i.Gid && !eventId.HasValue && !e.ActionOn.HasValue)
                 {
                     e.Action = i.Action;

                 }
                 else if ((e.Gid == i.Gid && eventId.HasValue) && (e.Action != i.Action || i.ActionOn == DateTime.MinValue))
                 {
                     e.Action = i.Action;
                     e.ActionOn = null;

                     foreach (InventoryGoodsEvents goodsEvent in inventoryGoodsEventsList)
                     {
                         context.InventoryGoodsEvents.DeleteOnSubmit(goodsEvent);

                         foreach (GoodsEvent ge in goodsEventList)
                         {
                             if (ge.Id == goodsEvent.EventId)
                             {
                                 ge.IsDeleted = true;
                                 ge.DeletedOn = DateTime.Now;
                                 ge.DeletedBy = System.Web.HttpContext.Current.User.Identity.Name;
                             }
                         }
                     }
                 }
                 ++index;
             }
         }
         context.SubmitChanges();
         scope.Complete();
     }
 }
public void UpdateInventoryGoods(列表,int-id)
{
int指数=0;
var query=来自context.inventoryGoods中的inventoryGoods
其中inventoryGoods.ParentId==id
选择库存商品;
List goodsList=query.ToList();
使用(var scope=new TransactionScope())
{
var allEvents=来自上下文中的invent.InventoryGoodsEvents
where goodsList.Contains(invent.InventoryGood)
选择发明;
List inventoryGoodsEventsList=allEvents.ToList();
var events=来自context.GoodsEvent中的g
选择g;
List goodsEventList=events.ToList();
foreach(清单中的库存货物i)
{
foreach(货物清单中的库存货物e)
{
如果(指数=30)
{