Pregunta

Tengo una consulta linq que devuelve el ID de una pregunta basada en el texto de las preguntas. Esta identificación es necesaria para relacionar una fecha en una tabla de fechas con esa pregunta en particular. La pregunta ya está almacenada y la fecha se almacena en un momento diferente.

El problema es que la consulta devuelve el questionID como un tipo anónimo y, por lo tanto, cuando necesito asignar ese questionID como questionID en otra tabla, arroja un error, indicando que la tabla espera un Guid. Después de esto, convertí el tipo anónimo en una cadena y luego usé la función de conversión de GUID para convertir la cadena en un GUID, sin embargo, ahora me da el error de que un GUID debe tener 32 caracteres y 4 guiones.

Mis pensamientos con respecto a esto son que el tipo anónimo está devolviendo el questionID como '' QuestionID = jkj939-89239829-, etc., etc. '' - Con el prefijo de caracteres en la parte delantera y, por lo tanto, al convertirlo en un GUID, la cadena convertida contiene estos caracteres.

¿Me he perdido algo? Realmente no puedo entender por qué haría esto, y ¿hay alguna manera de eliminar el prefijo devuelto por el tipo anónimo? La ayuda sería muy apreciada.

Aquí está el código:

public static void GetQuesID(string quesText)
    {
        ExamineDataContext dc = new ExamineDataContext();
        var matchedques = from q in dc.GetTable<Question>()
                            where q.QuestionText.Contains(quesText)
                            select new{
                                q.QuestionID
                            };
        foreach (var element in matchedques)
        {
            MessageBox.Show(element.ToString());
        }

        try
        {
            Guid g = Guid.NewGuid();
            Table<DateLastUsed> dlused = Repository.GetDateLastUsedTable();
            DateLastUsed dlu = new DateLastUsed(); ;
            string qidGuidString = matchedques.ToString();
            Guid convQuesGuid = new Guid(qidGuidString);
            dlu.DLUID = g;
            dlu.QuestionID = convQuesGuid;
            dlu.DateLastUsed1 = DateTime.Now;

            dlused.InsertOnSubmit(dlu);
            dlused.Context.SubmitChanges();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
¿Fue útil?

Solución

A menos que me falte algo, ¿por qué no simplemente selecciona q.QuestionID en lugar de crear un nuevo contenedor de tipo anónimo?

var matchedques = from q in dc.GetTable<Question>()
                            where q.QuestionText.Contains(quesText)
                            select q.QuestionID;

foreach (var element in matchedques)
{
    MessageBox.Show(element.ToString());
}

Alternativamente, asigne un nombre al campo (" theID " a continuación) y acceda directamente a él:

var matchedques = from q in dc.GetTable<Question>()
                            where q.QuestionText.Contains(quesText)
                            select new{
                                theID = q.QuestionID
                            };

foreach (var element in matchedques)
{
    MessageBox.Show(element.theID.ToString());
}

Aparentemente, había más en la pregunta de lo que pensaba. En respuesta al comentario, tenga en cuenta que está devolviendo una enumeración de resultados en coincidencias (de ahí el foreach anterior, ¿verdad?). Entonces la siguiente línea también está en error:

string qidGuidString = matchedques.ToString();

O quieres

string qidGuidString = matchedques.Single().ToString();

si los matchedques deben contener un solo resultado, o un bucle foreach si los matchedques deben contener múltiples resultados.


Tenga en cuenta que no hay ninguna razón para convertir un GUID a cadena y viceversa, y también puede usar la consulta para devolver algo más útil (es decir, un nuevo objeto DateLastUsed ):

var matchedques = from q in dc.GetTable<Question>()
                            where q.QuestionText.Contains(quesText)
                            select new DateLastUsed() {
                                DLUID = Guid.NewGuid(),
                                QuestionID = q.QuestionID,
                                DateLastUsed1 = DateTime.Now
                            };

Table<DateLastUsed> dlused = Repository.GetDateLastUsedTable();

foreach(var dlu in matchedques)
{
    dlused.InsertOnSubmit(dlu);
    dlused.Context.SubmitChanges();
}

Otros consejos

¿Por qué no simplemente seleccionar q.QuestionID; en lugar de este `select new {q.QuestionID}; ' cosas?

Está llamando a .ToString () en matchedques, que es una enumeración:

var matchedques = from q in dc.GetTable<Question>()
                            where q.QuestionText.Contains(quesText)
                            select new{
                                q.QuestionID
                            };

string qidGuidString = matchedques.ToString();

Entonces, en su ejemplo anterior, matchedques es una enumeración de tipos anónimos (probablemente debería eliminar eso y seleccionar q.QuestionID directamente). Llamar a ToString () sobre esto devolverá una representación de cadena del objeto, y no simplemente el QuestionId del primer elemento de la secuencia.

¿Espera que siempre haya un solo resultado para la consulta anterior? Si es así, probablemente debería mirar el operador Single.

Algo como esto debería hacer:

var matchedQuesId = 
    dc.GetTable<Question>()
    .Where(q =>q.QuestionText.Contains(quesText))
    .Single()
    .QuestionID;

En este caso, puede usar matchedQuesId directamente. Tenga en cuenta que si la consulta Where no coincide con ninguno, o más de un elemento, arrojará un error. Lea sobre el operador único para averiguar por qué.

Prueba esto:

var matchedques = (from q in dc.GetTable<Question>()
                  where q.QuestionText.Contains(quesText)
                  select new{
                      q.QuestionID
                  }).FirstOrDefault();

Entonces simplemente:

if (matchedques != null){
    // Just use matchedques.QuestionID to get your value
}

FirstOrDefault establecerá matchedques var en una sola instancia del objeto, no en una enumeración de ellos. Funciona de maravilla cuando sabes que solo hay un valor que deseas. El bit OrDefault significa que será NULL si no se encuentra nada.

Cambiar a:

...
var matchedques = from q in dc.GetTable<Question>()
                        where q.QuestionText.Contains(quesText)
                        select q.QuestionID;

p. eliminar new {...}, por lo que está creando un nuevo tipo anónimo con la propiedad id.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top