Question

I have a linq query which returns the ID of a question based on the questions text. This ID is then needed to be used to relate a date in a date table to that particular question. The question is already stored and the date is stored at a different time.

The problem is that the query returns the questionID as an anonymous type and so when I need to assign that questionID as the questionID in another table, it throws an error, stating that the table is expecting a Guid. Following this, I converted the anonymous type to a string and then used the GUIDs convert feature to convert the string to a GUID, however it is now giving me the error that a GUID should be 32 characters and 4 dashes.

My thoughts regarding this are that the anonymous type is returning the questionID as "QuestionID = jkj939-89239829- etc etc." - With the prefix of characters at the front, and thus when converting it to a GUID, the converted string contains these characters.

Have I missed something? I really can't understand why it would do this, and is there a way to remove the prefix returned by the anonymous type? Help would be greatly appreciated.

Here is the 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;
        }
    }
Was it helpful?

Solution

Unless I'm missing something, why don't you just select q.QuestionID instead of making a new anonymous-type wrapper?

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

Alternatively, give the field a name ("theID" below) and access it directly:

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

Apparently, there was more to the question than I first thought. In response to the comment, keep in mind that you're returning an enumeration of results in matchedques (hence the foreach above, right?). So the following line is also in error:

string qidGuidString = matchedques.ToString();

You either want

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

if matchedques should contain a single result, or a foreach loop if matchedques should contain multiple results.


Note that there's no reason to convert a GUID to string and back again, and you can also use the query to return something more useful (namely, a new DateLastUsed object):

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

OTHER TIPS

Why don't just select q.QuestionID; instead of this `select new { q.QuestionID };' stuff?

You are calling .ToString() on matchedques, which is an enumeration:

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

string qidGuidString = matchedques.ToString();

So in your example above, matchedques is an enunmeration of anonymous types (you should probably do away with that and select q.QuestionID directly). Calling ToString() on this will return a string representation of the object, and not simply the QuestionId of the first element of the sequence.

Are you expecting there to always be only one result for the above query? If so, you should probably look at the Single operator.

Something like this should do:

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

In this case, you can then use matchedQuesId directly. Note that if the Where query matches none, or more than one elements, this will throw an error. Read up on the Single operator to find out why.

Try this:

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

Then simply:

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

FirstOrDefault will set the matchedques var to a single instance of the object, not an ennumeration of them. Works a treat when you know there is just one value you want. The OrDefault bit means it will be NULL if nothing found.

Change to:

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

e.g. remove new {...}, so you are creating a new anonimouse type with the id property.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top