2014-01-22 50 views
0

我有一种情况,我必须根据记录是否有打开或关闭的项目将源记录列表状态列更新为打开或关闭状态 - 项目列表可以通过源项目的ID和项目中的客户端ID将多个项目链接到源记录,代码是检索客户项目,然后检查是否有结束日期,如果没有 - 它的开放 - 如果有的话 - 它的封闭。这些sharepoint列表很大Sharepoint 2010 - 更新大列表,处理非常缓慢和超时

我已经写了代码,基本上允许我指定一个开始ID,然后它会在停止之前处理这么多的记录,当我点击一个运行按钮时 - 我把这个放到位,因为这个过程非常缓慢甚至超时,但我不明白为什么它如此缓慢和不稳定 - 如果我尝试处理超过150条记录 - 超时,服务器本身是一个带有24GB内存的八核系统,所以我不会不认为它的服务器,它可能是我的代码。

protected void Button1_Click(object sender, EventArgs e) 
    { 
     SPWeb web = SPControl.GetContextWeb(this.Context); 
     string SPsiteUrl = SPContext.Current.Web.Url; 
     Label1.Text = "Running"; 
     int start; 
     start = Convert.ToInt32(TextBox1.Text); 
     start = int.Parse(TextBox1.Text); 
     int end = start + 150; 
     int count = 0; 

     using (SPSite oSite = new SPSite(SPsiteUrl)) 
     { 
      using (SPWeb oWeb = oSite.OpenWeb("/Client")) 
      { 
       // get lists 
       SPList oList = oWeb.Lists["Source Records"]; 
       SPList pList = oWeb.Lists["Project"]; 

       // query Source Records 
       string sQuery = @"<Where><And><Geq><FieldRef Name='ID' /><Value Type='Number'>" + start + "</Value></Geq><Leq><FieldRef Name='ID'/><Value Type='Number'> "+ end +"</Value></Leq></And></Where>"; 
       string sViewFields = @"<FieldRef Name='ID' />"; 
       string sViewAttrs = @"Scope=""Recursive"""; 
       uint iRowLimit = 0; 

       var oQuery = new SPQuery(); 
       oQuery.Query = sQuery; 
       oQuery.ViewFields = sViewFields; 
       oQuery.ViewAttributes = sViewAttrs; 
       oQuery.RowLimit = iRowLimit; 

       SPListItemCollection collListItems = oList.GetItems(oQuery); 

       // for each item 

       foreach (SPListItem oListItem in collListItems) 
       { 
        // get the client id 

        int id = oListItem.ID; 

         count = count + 1; 
         //Label1.Text = "Checking record" + id; 
         bool isopen = false; 
         // for each client id access the projects list 
         // query the closed date 
         string Query = @"<Where><Eq><FieldRef Name=""Client_x003a_ID"" /><Value Type=""Text"">" + id + "</Value></Eq></Where>"; 
         string pViewFields = @"<FieldRef Name=""End_x0020_Date"" />"; 
         string pViewAttrs = @"Scope=""Recursive"""; 
         uint pRowLimit = 0; 
         var pQuery = new SPQuery(); 
         pQuery.Query = Query; 
         pQuery.ViewFields = pViewFields; 
         pQuery.ViewAttributes = pViewAttrs; 
         pQuery.RowLimit = pRowLimit; 
         SPListItemCollection ListItems = pList.GetItems(pQuery); 

         foreach (SPListItem ListItem in ListItems) 
         { 
          try 
          { 
           DateTime enddate = (DateTime)ListItem["End_x0020_Date"]; 
           if (enddate != null) 
           { 
            isopen = false; 
           } 
           // else if the date is null set the open to true 
           else 
           { 
            isopen = true; 
           } 
          } 
          catch 
          { 
           string enddate = null; 
           if (enddate == null) 
           { 
            // if the end date is present set project closed to true 
            isopen = true; 
           } 
          } 

         // if project is open 
         if (isopen) 
         { 
          oWeb.AllowUnsafeUpdates = true; 
          SPListItem itemupdate = oWeb.Lists["Source Records"].Items.GetItemById(id); 
          itemupdate["Status"] = "Open"; 
          itemupdate.Update(); 
          oWeb.AllowUnsafeUpdates = false; 
          // set records on source record to open 
         } 
         //else // project is closed 
         //{ 
         // oWeb.AllowUnsafeUpdates = true; 
         // SPListItem itemupdate = oWeb.Lists["Source Records"].Items.GetItemById(id); 
         // itemupdate["Status"] = "Closed"; 
         // itemupdate.Update(); 
         // oWeb.AllowUnsafeUpdates = false; 
         // // set the record to closed 
         //} 
        } 
       } 
       Label1.Text = "Finished Number of records checked: " + count + " of " + collListItems.Count; 
      } 
     } 
    }' 
+0

的代码被编码后的文件从WSP拉 - 已经编辑到包括整个代码,包括注释掉的代码 – Carl

回答

-2

您需要更新嵌套循环的代码。取而代之的是:

foreach (SPListItem item1 in sPList.GetItems(sPQuery1)) 

尝试使用此:

SPListItemCollection items1 = sPList.GetItems(sPQuery1); 
foreach (SPListItem item1 in items1) 

请参阅本blog post了解详情。

更新:你必须尝试摆脱嵌套循环。我认为你可以通过在源列表中添加项目列表中的参考来实现该目标,并参考End Date列。

+0

嗨, 谢谢对于这个,但没有喜悦,我害怕.. – Carl

+1

你所建议的改变不会改变一件事情。 'foreach'循环只评估IEnumerable对象一次,而不是循环的每次迭代。这与您链接的博客帖子完全不同。 – Servy

1

代替

SPListItem itemupdate = oWeb.Lists["Source Records"].Items.GetItemById(id); 

试试这个:

SPListItem itemupdate = oWeb.Lists["Source Records"].GetItemById(id); 
+0

他的问题是他正在循环中执行复杂而昂贵的查询,而这正是他的主要成本所在。这种改变根本不会有太大的改变。 – Servy

+1

对不起,但我强烈反对在这里。 SPList.Items是一项非常昂贵的操作。基本上它会从列表中检索所有项目。它发生在一个循环中。所以。如果“源记录”列表中有1000-2000项,则需要花费大量时间考虑“foreach(SPListItem oListItem in collListItems)”。总的来说,这个代码有几个严重的问题,而不仅仅是一个。例如,SPWeb.Lists [“”]也是非常昂贵的操作,你应该从循环等移出 –

+0

但它只是有条件地发生。这是一个*问题,但它并没有改变这个算法的核心设计是有缺陷的。他不应该通过双重嵌套循环中的ID来获取项目*,除此之外,他甚至不应该*拥有双重嵌套循环,其中每个循环都表示一个数据库查询。所以虽然这确实解决了一些问题,但是当你完成之后,它仍然会留下一个破碎的解决方案 – Servy