当前位置:编程学习 > C#/ASP.NET >>

.Net LINQ查询优化


var State = from a in 表a where a.ParamType == 505 select a;//查询馆藏状态
for (int i = 0; i < State.Count(); i++){
     int StateID = State.ToList()[i].ParamIndex;  //馆藏状态
      string StateName = State.ToList()[i].ParamName;
var query = from p in 表b//查询总价
              join q in 表c on p.RecordID
            equals q.RecordID
            where p.State == StateID
            group p by p.VolumeSinglePrice into g
            select new
            {
            key = g.Key,
            count = g.Count()
            };
foreach (var zj1 in query2)
{
  for (int k = 0; k < zj1.count; k++)
  {
    zj = zj + zj1.key;
  }
}
}

在程序运行到foreach()时报超时错误,请问怎么优化 有7w+条数据 --------------------编程问答-------------------- foreach (var zj1 in query2)
{
  for (int k = 0; k < zj1.count; k++)
  {
    zj = zj + zj1.key;
  }
}
红色部分循环干嘛。 --------------------编程问答-------------------- 外层的for循环没必要:
var query = from p in 表b//查询总价
            join q in 表c on p.RecordID  equals q.RecordID
            where 表a.Where(a=>a.ParamType == 505).Contains(p.State )
            group p by p.VolumeSinglePrice into g
            select new
            {
            key = g.Key,
            count = g.Count()
            };


foreach代码没看懂你什么意思,query2哪冒出来的 --------------------编程问答-------------------- 没看明白,StateName有啥用??? --------------------编程问答--------------------
引用 2 楼 q107770540 的回复:
外层的for循环没必要:


C# code
?



123456789

var query = from p in 表b//查询总价             join q in 表c on p.RecordID  equals q.RecordID             where 表a.Where(a=>a.ParamType == 505).Contains(p.S……

StateID不只是一个,外层for循环得到StateID,query2就是上面的query --------------------编程问答--------------------
引用 3 楼 hjywyj 的回复:
没看明白,StateName有啥用???

StateName在下面有用,那段代码没贴上去 --------------------编程问答--------------------
引用 1 楼 Chinajiyong 的回复:
foreach (var zj1 in query2)
{
  for (int k = 0; k < zj1.count; k++)
  {
    zj = zj + zj1.key;
  }
}
红色部分循环干嘛。

把zj1.key的值累加给zj --------------------编程问答-------------------- 我当然知道StateID不止一个,所以我在查询代码用的是
where 表a.Where(a=>a.ParamType == 505).Contains(p.State ) --------------------编程问答-------------------- zj=query.SelectMany(x=>x.Key).Sum(); --------------------编程问答--------------------
引用 8 楼 q107770540 的回复:
zj=query.SelectMany(x=>x.Key).Sum();

这样报错 --------------------编程问答-------------------- 我对Linq不是太熟,不知道这样有用吗

select new
            {
            key = g.Key,
            count = sum(g.key)
            }; --------------------编程问答--------------------
引用 10 楼 zhao8848jun 的回复:
我对Linq不是太熟,不知道这样有用吗

select new
            {
            key = g.Key,
            count = sum(g.key)
            };

count返回的是int型,g.key是decimal型, --------------------编程问答--------------------

var State = (from a in 表a 
             where a.ParamType == 505
             select a).ToList();/*在这里  linq你写出来后程序都没有帮你把结果查出来
直到你去ToList或者AsEnumerable或者foreach等之类的操作的时候才会去执行这个查询
而且你之后会遍历它 相当于这些数据是不需要再去筛选直接使用的  那我在这里就直接ToList出来
放在内存里  也好比你在for循环里一个一个的去tolist */
for (int i = 0; i < State.Count(); i++){
     int StateID = State[i].ParamIndex;  //馆藏状态
     string StateName = State[i].ParamName;
     var query = from p in 表b//查询总价
                 join q in 表c on p.RecordID equals q.RecordID
                 where p.State == StateID
                 group p by p.VolumeSinglePrice into g
                 select g.Count()*g.key;/* 我发现你后面个循环 你的count是多大  那它对应的
key就叠加多少次  那我在这里就直接吧结果计算出来 */
/* 这里判断query里是否存在结果  存在的条件下再去叠加到你的zj里
 如果不判断而直接去Sum()那在没有元素的情况下是会报错的 */
     if(query.Count()>0)
     {
         zj+=query.Sum();
     }
}

这是我对lz代码的理解  有什么错误的地方望大神们指出  谢谢... --------------------编程问答--------------------
引用 12 楼 lonions 的回复:
C# code
?



1234567891011121314151617181920212223

var State = (from a in 表a               where a.ParamType == 505              select a).ToList();/*在这里  linq你写出来后程序都没有帮你把结果查出来 直到你去ToList或者As……

这样也不行。if(query.Count()>0)这里报错
var query2 = from p in collection//查询总价
                                         join q in Biblios on p.RecordID
                                         equals q.RecordID
                                         where p.State == StateID
                                         group p by p.VolumeSinglePrice into g
                                         select g.Count() * g.Key;
var query2 = from p in collection//查询总价
                                         join q in Biblios on p.RecordID
                                         equals q.RecordID
                                         where p.CirDocTypeID == CirDocTypeID
                                         group p by p.VolumeSinglePrice into g
                                         select new
                                         {
                                             key = g.Key,
                                             count=g.Count()
                                         };
这是两段相同的代码,只是where条件不同,后一条代码可以执行,前一条代码就报超时的错 --------------------编程问答--------------------
引用 13 楼 xhs869177713 的回复:
引用 12 楼 lonions 的回复:C# code
?



1234567891011121314151617181920212223

var State = (from a in 表a               where a.ParamType == 505              select a).ToList();/*在这里  linq……

恩  还是帮lz顶下  坐等正解... --------------------编程问答-------------------- var State = from a in 表a where a.ParamType == 505 select a;//查询馆藏状态
for (int i = 0; i < State.Count(); i++){
     int StateID = State.ToList()[i].ParamIndex;  //馆藏状态
      string StateName = State.ToList()[i].ParamName;
var query = from p in 表b//查询总价
              join q in 表c on p.RecordID
            equals q.RecordID
            where p.State == StateID
            group p by p.VolumeSinglePrice into g
            select new
            {
            key = g.Key,
            count = g.Count()
            };

说真的,LZ 给的 SAMPLE 太乱,看不懂

原则是,不要把任何 linq db query 放在 loop 里面。你上面的这一段翻译出来大概是

第一个 query 完全没必要,其实就是一个 join,下面的语句会自动帮你 join

var queryRecord = from p in context.Volumne 
                  from q in context.Record.Where( i=> i.RecordID == p.RecordI ) 
                  where p.StateParent.ParamType == 505 
                  group p by p.VolumeSinglePrice into g
                  select new { key = g.Key, count = g.Count()};

假设你这个有 7w+ 数据,那么你程序的应用是有必要更改,或者可以使用 asycn 的方法,或者可以使用 paging, 或者可以使用 prevention 的方法,比如先做个 count, 如果超过 1W,就要求用户提供更多条件来减少返回的记录等等

--------------------编程问答-------------------- 帮顶,我来学习,有正确的答案么 --------------------编程问答--------------------
引用 楼主 xhs869177713 的回复:
for (int i = 0; i < State.Count(); i++){
     int StateID = State.ToList()[i].ParamIndex;  //馆藏状态

后边的代码懒得看了!

仅这两还来看,就有着能让“呕吐”的性能问题。

你知道Linq是延迟执行的么?

那么这里就会重复去执行“查询馆藏状态”无数次。比如说馆藏有1万,那么你这里就会执行2万次完全一模一样的重复查询!

这里应该写

var StateList = State.ToList();
for (int i = 0; i < StateList.Count(); i++){
     int StateID = StateList[i].ParamIndex;  //馆藏状态
--------------------编程问答-------------------- 后边的代码懒得看。你对Linq的了解实在是差的离谱。 --------------------编程问答-------------------- Linq"慢"就是这么来的! --------------------编程问答-------------------- 7W+的数据一下子放到内存里? --------------------编程问答--------------------


var State = from a in 表a where a.ParamType == 505 select a;//查询馆藏状态
for (int i = 0; i < State.Count(); i++){
     int StateID = State.ToList()[i].ParamIndex;  //馆藏状态
      string StateName = State.ToList()[i].ParamName;
var query = from p in 表b//查询总价
              join q in 表c on p.RecordID
            equals q.RecordID
            where p.State == StateID
            group p by p.VolumeSinglePrice into g
            select new
            {
            key = g.Key,
            count = g.Count()
            };
/*下面这段循环必须要放在for中吗?我好想没有看到跟for中关联的地方zj是for外面定义的嘛?
希望楼主给个全一点的代码,并把需要实现什么过程叙述一下~这样有助于大家理解
*/
foreach (var zj1 in query2)
{
  for (int k = 0; k < zj1.count; k++)
  {
    zj = zj + zj1.key;
  }
}
}


补充:.NET技术 ,  LINQ
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,