2011-03-08 12 views
5

Estoy haciendo un código personalizado para un elemento web de SharePoint en C#. Específicamente, estoy haciendo una prueba, mi principal punto aquí es abordar la lista que contiene la pregunta, las opciones de respuesta y la respuesta correcta.C# más eficiente iteración de lista de SharePoint

En la última etapa del cuestionario necesito verificar las respuestas seleccionadas por el usuario contra la respuesta correcta en la lista. Actualmente, estoy haciendo lo siguiente para verificar si cada uno es correcto, lo cual supongo que no es muy eficiente porque itera a través de cada pregunta. ¿Hay algún método, específicamente para el bucle foreach de SPList, que sea más eficiente?

   // 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.... 
+0

¿Dónde se está ejecutando este código (receptor del evento? ¿Webpart?) ¿Está tratando de evitar calificar cada cuestionario cada vez? No estoy seguro de por qué está tratando de optimizar ... –

+0

El cuestionario se ejecuta en un elemento web, y tengo dos inquietudes: 1. Cuando lanzamos el cuestionario, es probable que tenga un aumento tal vez unos cientos de personas lo tomen y quiero para minimizar los cuellos de botella. 2. Esta es la primera programación de ASP.NET que he hecho y dado que trabajo principalmente en PHP, los diseños y la programación de OO me desaniman. Además, he leído algunos blogs que dicen que este método de iteración a través de la lista es muy ineficiente. –

+0

Bueno, si su lista de "Preguntas" contiene todas las preguntas que aparecen en el cuestionario y necesita validar la respuesta de cada usuario, entonces diría que un foreach está bien. –

Respuesta

3

Si necesita tener acceso a cada elemento de la lista, a continuación, utilizando un foreach está perfectamente bien:

SPList answerList = myWeb.Lists[questionList]; 
foreach (SPListItem quizEntry in answerList.Items) 
{ 
    // todo... 
} 

En general, la mayoría de las personas necesita trabajar con un subconjunto de elementos de una lista. En este caso, lo más probable es que desee recuperar un subconjunto de elementos de la lista y luego realice su procesamiento. Por ejemplo, mediante el uso de SPQuery y SPList.GetItems (code from the full example here):

// 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 ... Aquí es un buen enlace repasando algunas otras opciones: https://www.nothingbutsharepoint.com/sites/devwiki/SP2007Dev/Pages/Accessing%20list%20items%20using%20the%20object%20model.aspx

SharePoint tiene una gran cantidad de herramientas. Siempre vale la pena determinar qué herramienta es la correcta para el trabajo en cuestión. :)

+0

Si la lista contiene quizás 200-300 entradas, ¿cree que es más eficiente consultar la lista con SPQuery (para obtener los 20-30 que necesito), o simplemente usar foreach para recorrer cada uno de ellos? Me gusta su comentario de que 'SharePoint tiene muchas herramientas'. En general, me resulta difícil de usar, en gran parte porque no puedo encontrar ninguna fuente de documentación decente. –

+0

Definitivamente debería usar SPQuery. Cuando repite el uso de un foreach sobre 'SPList.Items', recuperará TODOS los elementos de la lista del db. Primero querrá usar 'SPQuery' para obtener el subconjunto de elementos y ** luego ** usar el foreach para iterar sobre' SPListItemCollection items' devuelto de 'list.GetItems (query)'. –

+0

¿Qué declaración de importación debo usar? – SearchForKnowledge

1

Esto puede parecer tonto, pero en lugar de utilizar una clase para almacenar las variables por qué no utilizar una matriz simple? O una forma aún más fácil sería escribir una consulta SQL para comparar el conjunto de respuestas con las respuestas almacenadas en la base de datos. Su solución parece ser mucho más ortodoxa, pero tal vez solo soy yo.

También se fijan en respuesta Performance of Arrays vs. Lists

Parece que sería más rápido que utilizar un bucle de un bucle foreach para iterar sobre una lista.

+0

No creo que su respuesta se aplique al uso de un foreach con SPList (un objeto de SharePoint). Además, utilizar un bucle for con SPList.Items está bien siempre que lo haga correctamente: http://blog.dynatrace.com/2009/01/11/the-wrong-way-to-iterate-through-sharepoint -splist-items/ –

+0

@Kit Menke, ese es un buen punto que estaba buscando en el algoritmo y no en la API. –

1

Me imagino que usando el SpList.GetItems con una consulta correctamente formateada le dará la cantidad de respuestas correctas.

La herramienta U2U CAML Query Builder puede ser útil para obtener una consulta correcta.

0

¿Por qué no utilizar LINQ en Sharepoint? Es realmente fácil y sin necesidad de bucle

es decir

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(); 

que aquí hay una guía para utilizar LINQ in Sharepoint

Cuestiones relacionadas