Question

J'ai une requête linq qui renvoie l'ID d'une question en fonction du texte de la question. Cet identifiant doit ensuite être utilisé pour associer une date dans une table de dates à cette question particulière. La question est déjà enregistrée et la date est enregistrée à une heure différente.

Le problème est que la requête renvoie l'ID de question sous forme de type anonyme. Par conséquent, lorsque je dois affecter cet ID de question en tant qu'interrogation de question dans une autre table, une erreur est générée, indiquant que la table attend un Guid. Après cela, j’ai converti le type anonyme en chaîne, puis j’ai utilisé la fonction de conversion GUID pour convertir la chaîne en GUID. Cependant, il me donne maintenant l’erreur qu’un GUID doit comporter 32 caractères et 4 tirets.

Mon opinion à ce sujet est que le type anonyme renvoie l'ID questionID sous la forme "QuestionID = jkj939-89239829- etc.". - Avec le préfixe des caractères à l'avant, et donc lors de la conversion en GUID, la chaîne convertie contient ces caractères.

Ai-je oublié quelque chose? Je ne comprends vraiment pas pourquoi il ferait cela, et existe-t-il un moyen de supprimer le préfixe renvoyé par le type anonyme? De l'aide serait grandement appréciée.

Voici le code:

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;
        }
    }
Était-ce utile?

La solution

Sauf s'il me manque quelque chose, pourquoi ne pas simplement sélectionner q.QuestionID au lieu de créer un nouveau wrapper de type anonyme?

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

Vous pouvez également attribuer un nom au champ (" theID "ci-dessous) et y accéder directement:

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

Apparemment, la question était plus vaste que je ne le pensais au départ. En réponse au commentaire, n'oubliez pas que vous retournez une énumération de résultats en matchedques (d'où le foreach ci-dessus, n'est-ce pas?). La ligne suivante est donc également en erreur:

string qidGuidString = matchedques.ToString();

Vous voulez soit

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

si matchedques doit contenir un seul résultat, ou une boucle foreach si matchedques doit contenir plusieurs résultats.

Notez qu'il n'y a aucune raison de convertir un GUID en chaîne et vice-versa, et vous pouvez également utiliser la requête pour retourner quelque chose de plus utile (à savoir, un nouvel objet 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();
}

Autres conseils

Pourquoi ne pas simplement sélectionner q.QuestionID; au lieu de ceci `select new {q.QuestionID}; ' des trucs?

Vous appelez .ToString () sur matchedques, qui est une énumération:

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

string qidGuidString = matchedques.ToString();

Donc, dans votre exemple ci-dessus, matchedques est une énumération de types anonymes (vous devriez probablement vous en passer et sélectionner directement q.QuestionID). Si vous appelez ToString () à ce sujet, vous obtiendrez une représentation sous forme de chaîne de l’objet, et pas simplement l’ID QuestionId du premier élément de la séquence.

Vous attendez-vous à ce qu'il n'y ait toujours qu'un seul résultat pour la requête ci-dessus? Si c'est le cas, vous devriez probablement regarder l'opérateur unique.

Quelque chose comme ça devrait faire:

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

Dans ce cas, vous pouvez utiliser directement matchedQuesId. Notez que si la requête Where ne correspond à aucun, ou à plusieurs éléments, une erreur sera générée. Consultez l'opérateur unique pour savoir pourquoi.

Essayez ceci:

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

Puis simplement:

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

FirstOrDefault définira la var matchedques sur une seule instance de l'objet, et non sur leur énumération. Travaille un régal quand vous savez qu'il y a juste une valeur que vous voulez. Le bit OrDefault signifie qu'il sera NULL si rien n'est trouvé.

Changer en:

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

par exemple. supprime new {...} pour créer un nouveau type anonyme avec la propriété id.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top