C # Linq Guid Проблема анонимного типа - PullRequest
2 голосов
/ 05 мая 2009

У меня есть запрос linq, который возвращает идентификатор вопроса на основе текста вопросов. Затем этот идентификатор необходимо использовать, чтобы связать дату в таблице дат с этим конкретным вопросом. Вопрос уже сохранен, а дата хранится в другое время.

Проблема в том, что запрос возвращает questionID как анонимный тип, и поэтому, когда мне нужно назначить этот questionID в качестве questionID в другой таблице, он выдает ошибку, утверждая, что таблица ожидает Guid. После этого я преобразовал анонимный тип в строку, а затем использовал функцию преобразования GUID для преобразования строки в GUID, однако теперь я получаю сообщение об ошибке, что GUID должен быть 32 символа и 4 тире.

По этому поводу я думаю, что анонимный тип возвращает questionID как "QuestionID = jkj939-89239829- и т. Д. И т. Д." - С префиксом символов спереди и, следовательно, при преобразовании его в GUID преобразованная строка содержит эти символы.

Я что-то пропустил? Я действительно не могу понять, почему он это сделал, и есть ли способ удалить префикс, возвращаемый анонимным типом? Помощь будет принята с благодарностью.

Вот код:

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

Ответы [ 5 ]

4 голосов
/ 05 мая 2009

Если я что-то упустил, почему бы вам просто не сделать select q.QuestionID вместо создания новой обертки анонимного типа?

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

В качестве альтернативы присвойте полю имя ("theID" ниже) и получите к нему прямой доступ:

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

Видимо, в этом вопросе было больше, чем я думал. В ответ на комментарий, имейте в виду, что вы возвращаете перечисление результатов в matchedques (отсюда и foreach выше, верно?). Поэтому следующая строка также содержит ошибку:

string qidGuidString = matchedques.ToString();

Вы либо хотите

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

если совпадения должны содержать один результат, или цикл foreach, если совпадения должны содержать несколько результатов.


Обратите внимание, что нет смысла преобразовывать GUID в строку и обратно, и вы также можете использовать запрос для возврата чего-то более полезного (а именно, нового 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();
}
1 голос
/ 01 марта 2012

Попробуйте это:

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

Тогда просто:

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

FirstOrDefault установит переменную matchedques для одного экземпляра объекта, а не для их перечисления Создает удовольствие, когда вы знаете, что вам нужно только одно значение. Бит OrDefault означает, что он будет NULL, если ничего не найдено.

1 голос
/ 05 мая 2009

Вы вызываете .ToString () для совпадений, что является перечислением:

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

string qidGuidString = matchedques.ToString();

Так что в приведенном выше примере matchedques - это перечисление анонимных типов (вам, вероятно, следует покончить с этим и напрямую выбрать q.QuestionID). Вызов ToString () для этого вернет строковое представление объекта, а не просто QuestionId первого элемента последовательности.

Ожидаете ли вы, что для вышеуказанного запроса всегда будет только один результат? Если это так, вам, вероятно, следует взглянуть на оператор Single.

Что-то вроде этого должно сделать:

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

В этом случае вы можете напрямую использовать matchedQuesId. Обратите внимание, что если запрос Where не соответствует ни одному или нескольким элементам, это приведет к ошибке. Узнайте, почему оператор Single.

1 голос
/ 05 мая 2009

Почему бы просто не select q.QuestionID; вместо этого `select new {q.QuestionID}; ' материал

0 голосов
/ 05 мая 2009

Изменить на:

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

например. удалить новый {...}, поэтому вы создаете новый анонимный тип со свойством id.

...