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)
{