views:

3211

answers:

4

Hello,

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;
        }
    }
+1  A: 

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

Anton Gogolev
+1 Beat me to it by 35 secs.
lc
I tried that, changing the code to: dlu.QuestionID = matchedques;Recieved this:Error:Cannot implicitly convert type 'System.Linq.IQueryable<System.Guid>' to 'System.Guid' C:\Documents and
Goober
sahgilbert - see my answer below
Winston Smith
A: 

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();
}
lc
I tried that, changing the code to: dlu.QuestionID = matchedques;Recieved this:Error:Cannot implicitly convert type 'System.Linq.IQueryable<System.Guid>' to 'System.Guid' C:\Documents and
Goober
I edited the answer to address this.
lc
Hello, I implemented the code sample you posted above, and now although the code fires without any errors as it was before, it isn't actually inserting any new details.
Goober
Try inserting a breakpoint in the foreach loop. Expand the results of matchedques and see if you're getting the results you want. At this point I'm not sure whether the error is in the code above, the results of dc.GetTable<Question>(), or something happening in dlused.Context.SubmitChanges()...
lc
A: 

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.

Kamarey
If you vote down, please specify the reason. What problem with this answer?
Kamarey
A: 

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.

Winston Smith