Pergunta

Eu tenho uma consulta linq que retorna o ID de uma pergunta com base no texto perguntas. é então necessário este ID a ser usado para relacionar uma data em uma tabela de data para essa pergunta particular. A questão já está armazenado ea data é armazenada em um horário diferente.

O problema é que a consulta retorna o QuestionID como um tipo anônimo e assim quando eu preciso atribuir esse QuestionID como o QuestionID em outra tabela, ele lança um erro, informando que a tabela está esperando um Guid. Depois disso, eu converti o tipo anônimo para uma string e, em seguida, usou os GUIDs converter recurso para converter a string para um GUID, no entanto, é agora me dando o erro que um GUID deve ser 32 caracteres e 4 traços.

Os meus pensamentos sobre este são de que o tipo anônimo está retornando o QuestionID como "QuestionID = jkj939-89239829- etc etc." -. Com o prefixo de caracteres na frente, e, portanto, ao converter-lo para um GUID, a cadeia convertida contenha estes caracteres

eu perdi alguma coisa? Eu realmente não posso entender por que ele faria isso, e se existe uma maneira de remover o prefixo retornado pelo tipo anônimo? Ajuda seria muito apreciada.

Aqui está o 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;
        }
    }
Foi útil?

Solução

A menos que eu estou faltando alguma coisa, por que você não apenas select q.QuestionID em vez de fazer um novo tipo anônimo invólucro?

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

Como alternativa, dar o campo um nome ( "theID" abaixo) e acessá-lo diretamente:

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, havia mais para a questão do que eu pensava. Em resposta ao comentário, tenha em mente que você está retornando um enumeração dos resultados em matchedques (daí o foreach acima, certo?). Então a seguinte linha também está em erro:

string qidGuidString = matchedques.ToString();

Você quer quer

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

Se matchedques deve conter um único resultado, ou um loop foreach se matchedques deve conter vários resultados.


Note que não há nenhuma razão para converter um GUID para string e vice-versa, e você também pode usar a consulta para retornar algo mais útil (ou seja, um novo 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();
}

Outras dicas

Por que não apenas select q.QuestionID; em vez deste `selecionar nova {q.QuestionID};' material?

Você está chamando .ToString () no matchedques, que é uma enumeração:

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

string qidGuidString = matchedques.ToString();

Assim, no seu exemplo acima, matchedques é um enunmeration de tipos anônimos (você provavelmente deve acabar com isso e seleccionar q.QuestionID diretamente). Chamando ToString () nesse irá retornar uma representação de string do objeto, e não simplesmente o QuestionID do primeiro elemento da seqüência.

Você está esperando que haja sempre um só resultado para a consulta acima? Se assim for, você provavelmente deve olhar para o operador único.

Algo como isso deve fazer:

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

Neste caso, você pode usar matchedQuesId diretamente. Note-se que se o Onde consulta corresponde a nenhum, ou mais de um elementos, isto irá lançar um erro. Leia-se sobre o operador único para descobrir o porquê.

Tente isto:

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

Em seguida, basta:

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

FirstOrDefault irá definir o matchedques var a uma única instância do objeto, não um ennumeration deles. Funciona um deleite quando você sabe que não é apenas um valor desejado. Os meios OrDefault bit será NULL se nada encontrou.

Change to:

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

por exemplo. remover novo {...}, então você está criando um novo tipo anonimouse com a propriedade id.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top