最高效的C# SharePoint列表迭代

5
我正在用C#为SharePoint网页部件编写一些自定义代码,具体来说,我正在制作一个测验,我的主要重点是处理包含问题、答案选项和正确答案的列表。
在测验的最后阶段,我需要将用户选择的答案与列表中的正确答案进行比较。目前,我正在使用以下方法来检查每个答案是否正确,但我认为这并不是很有效率,因为它会迭代每个问题。是否有一种更有效的方法,特别是针对SPList foreach循环的方法?
                // 1. Store questions and answers in class
                    List<submittedAnswers> answeredQuestions = new List<submittedAnswers>();

                // 2. From POST pull answered question IDs and answer IDs (which correspond to the question primary key and answer choice number both stored in the list)
                    // INSERT BEAUTFIUL AND EFFICIENT WHILE LOOP HERE

                // 3. Loop through each question is list, if question was given, test if correct/incorrect
                using (SPWeb myWeb = mySite.OpenWeb())
                {
                    SPList answerList = myWeb.Lists[questionList];
                    foreach (SPListItem quizEntry in answerList.Items)
                    {
                        int pullAnswerId = int.Parse(quizEntry["Answer"].ToString()); // Pull answer number from list
                        int pullQuestionId = int.Parse(quizEntry["ID"].ToString()); // Pull primary key of question

                        submittedAnswers result = answeredQuestions.Find(delegate(submittedAnswers e) { return e.questionId == int.Parse(quizEntry["ID"].ToString()); });
                        if (result != null)
                        {
                            if (result.responseId != pullAnswerId) // If the response was different from the answer
                                incorrectAnswers++;
                            else
                                correctAnswers++;
                        }
                    }
                }
                // C# quiz grading magic here....

这段代码在哪里运行(事件接收器?WebPart?)您是否试图避免每次都对测验进行评分?不确定您为什么要进行优化... - Kit Menke
这个测验正在网页部件中运行,我有两个问题:1. 当我们发布测验时,可能会有几百人参加,我想尽量减少瓶颈。2. 这是我第一次做ASP.NET编程,因为我主要在PHP中工作,面向对象的设计和编程让我感到困惑。此外,我读了几篇博客,说这种遍历列表的方法非常低效。 - Eric Di Bari
如果你的“Questions”列表包含了测验中出现的所有问题,并且你需要验证每个用户的答案,那么我认为使用 foreach 是可以的。 - Kit Menke
那听起来像是我正在寻找的答案。太遗憾了,我不能将您的评论标记为答案... - Eric Di Bari
4个回答

3
如果需要访问列表中的每个项,那么使用 foreach 是完全可以的:
SPList answerList = myWeb.Lists[questionList];
foreach (SPListItem quizEntry in answerList.Items)
{
    // todo...
}

通常,大多数人需要使用列表中的子集。在这种情况下,您最有可能想要从列表中检索子集,然后进行处理。例如,通过使用SPQuery和SPList.GetItems (完整示例代码在此处):

// Build a query.
SPQuery query = new SPQuery();
query.Query = string.Concat(
                    "<Where><Eq>",
                        "<FieldRef Name='Status'/>",
                        "<Value Type='CHOICE'>Not Started</Value>",
                    "</Eq></Where>",
                    "<OrderBy>",
                        "<FieldRef Name='DueDate' Ascending='TRUE' />",
                        "<FieldRef Name=’Priority’ Ascending='TRUE' />", 
                    "</OrderBy>");                    

query.ViewFields = string.Concat(
                          "<FieldRef Name='AssignedTo' />",
                          "<FieldRef Name='LinkTitle' />",
                          "<FieldRef Name='DueDate' />",
                          "<FieldRef Name='Priority' />");

query.ViewFieldsOnly = true; // Fetch only the data that we need.

// Get data from a list.
string listUrl = web.ServerRelativeUrl + "/lists/tasks";
SPList list = web.GetList(listUrl);
SPListItemCollection items = list.GetItems(query);

FYI...这里有一个很好的链接,介绍了其他一些选项:https://www.nothingbutsharepoint.com/sites/devwiki/SP2007Dev/Pages/Accessing%20list%20items%20using%20the%20object%20model.aspx SharePoint拥有许多工具。始终值得确定哪个工具最适合当前的工作。 :)

如果列表包含大约200-300个条目,您认为使用SPQuery查询列表(以获取我需要的20-30个)更有效,还是只需使用foreach迭代每个条目?我喜欢您的评论,“SharePoint有很多工具”。总体而言,我发现它很难使用,主要是因为我找不到任何好的文档来源。 - Eric Di Bari
你应该使用SPQuery。当你使用foreach迭代SPList.Items时,它会从数据库中检索列表中的所有项。你首先需要使用SPQuery获取子集,然后使用foreach迭代从list.GetItems(query)返回的SPListItemCollection items - Kit Menke
我需要使用哪个导入语句? - SearchForKnowledge
1
@SearchForKnowledge SPListItemCollection 属于 Microsoft.SharePoint 命名空间。您需要引用服务器端 API 的一部分,即 Microsoft.SharePoint.dll。 - Kit Menke

1

这可能看起来很愚蠢,但是为什么不使用一个简单的数组来存储变量,而不是使用类呢?或者更简单的方法是编写一个SQL查询,将答案数组与存储在数据库中的答案进行比较。你的解决方案似乎过于面向对象,但也许只是我这个人太笨了。

另外,请查看数组与列表的性能表现

使用for循环迭代列表似乎比使用foreach循环更快。


我不认为你的答案适用于使用 foreach 循环遍历 SPList(一种 SharePoint 对象)。此外,只要你正确使用 SPList.Items 和 for 循环,就可以使用它:http://blog.dynatrace.com/2009/01/11/the-wrong-way-to-iterate-through-sharepoint-splist-items/。 - Kit Menke
@Kit Menke,你说得很好。我一直在看算法而不是API。 - Zen Devel

1

0
为什么不在Sharepoint中使用LINQ呢?它非常简单,而且不需要循环。

i.e

SPLinqDataContext dc = new SPLinqDataContext(SPContext.Current.Web.Url);

EntityList<QuizItem> Answers = dc.GetList<QuizItem>("Quiz");
EntityList<QuestionsItem> Questions = dc.GetList<QuestionsItem>("Questions");

int iCorrectAnswers = (from q in Questions
            from a in Answers
            where (q.Question == a.Question) && (q.CorrectAnswer == a.Answer)
            select a).Count();

int iWrongAnswers = (from q in Questions
                        from a in Answers
                        where (q.Question == a.Question) && (q.CorrectAnswer != a.Answer)
                        select a).Count();

这里有一个使用Sharepoint中的LINQ的指南


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接