Domanda

Ho una query linq che restituisce l'ID di una domanda in base al testo delle domande. È quindi necessario utilizzare questo ID per collegare una data in una tabella delle date a quella domanda specifica. La domanda è già memorizzata e la data è memorizzata in un altro momento.

Il problema è che la query restituisce il questionID come un tipo anonimo e quindi quando devo assegnare quel questionID come questionID in un'altra tabella, genera un errore, affermando che la tabella si aspetta un Guid. Successivamente, ho convertito il tipo anonimo in una stringa e quindi ho utilizzato la funzione di conversione dei GUID per convertire la stringa in un GUID, tuttavia ora mi dà l'errore che un GUID dovrebbe essere di 32 caratteri e 4 trattini.

Le mie considerazioni al riguardo sono che il tipo anonimo sta restituendo il questionID come " QuestionID = jkj939-89239829- etc etc " - Con il prefisso di caratteri nella parte anteriore e quindi quando lo si converte in GUID, la stringa convertita contiene questi caratteri.

Ho perso qualcosa? Non riesco davvero a capire perché lo farebbe, e c'è un modo per rimuovere il prefisso restituito dal tipo anonimo? L'aiuto sarebbe molto apprezzato.

Ecco il codice:

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;
        }
    }
È stato utile?

Soluzione

A meno che non mi manchi qualcosa, perché non basta selezionare q.QuestionID invece di creare un nuovo wrapper di tipo anonimo?

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

In alternativa, dai al campo un nome (" theID " sotto) e accedi direttamente ad esso:

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

Apparentemente, alla domanda c'era più di quanto pensassi. In risposta al commento, tieni presente che stai restituendo una enumerazione dei risultati in matchedques (da cui la foreach sopra, giusto?). Quindi anche la seguente riga è in errore:

string qidGuidString = matchedques.ToString();

O vuoi

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

se i matchedques devono contenere un singolo risultato, oppure un ciclo foreach se i matchedques devono contenere più risultati.


Nota che non c'è motivo per convertire un GUID in stringa e viceversa, e puoi anche usare la query per restituire qualcosa di più utile (vale a dire un nuovo oggetto 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();
}

Altri suggerimenti

Perché non selezionare q.QuestionID; invece di questo `selezionare new {q.QuestionID}; ' roba?

Stai chiamando .ToString () su matchedques, che è un elenco:

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

string qidGuidString = matchedques.ToString();

Quindi, nel tuo esempio sopra, matchedques è un inondazione di tipi anonimi (probabilmente dovresti eliminarlo e selezionare direttamente Q.QuestionID). Chiamare ToString () su questo restituirà una rappresentazione in forma di stringa dell'oggetto, e non semplicemente il QuestionId del primo elemento della sequenza.

Ti aspetti che ci sia sempre un solo risultato per la query sopra? In tal caso, dovresti probabilmente guardare l'operatore Single.

Qualcosa del genere dovrebbe fare:

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

In questo caso, puoi utilizzare direttamente matchedQuesId. Se la query Where non corrisponde a nessuno o più di un elemento, verrà generato un errore. Leggi su Operatore singolo per scoprire perché.

Prova questo:

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

Quindi semplicemente:

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

FirstOrDefault imposterà la var matchedques su una singola istanza dell'oggetto, non una loro numerazione. Funziona a meraviglia quando sai che c'è solo un valore che desideri. Il bit OrDefault indica che sarà NULL se non viene trovato nulla.

Cambia in:

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

es. rimuovi nuovo {...}, quindi stai creando un nuovo tipo anonimo con la proprietà id.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top