Проблема с анонимным типом Guid C # Linq
-
05-07-2019 - |
Вопрос
У меня есть запрос linq, который возвращает идентификатор вопроса на основе текста вопросов.Затем этот идентификатор необходимо использовать для привязки даты в таблице дат к этому конкретному вопросу.Вопрос уже сохранен, а дата сохранена в другое время.
Проблема в том, что запрос возвращает QuestionID как анонимный тип, и поэтому, когда мне нужно назначить этот QuestionID в качестве QuestionID в другой таблице, он выдает ошибку, указывающую, что таблица ожидает Guid.После этого я преобразовал анонимный тип в строку, а затем использовал функцию преобразования GUIDs для преобразования строки в 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;
}
}
Решение
Если я что-то не упустил, почему бы вам просто не выбрать 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();
}
Другие советы
Почему бы просто не выбрать q.QuestionID;
вместо этого `select new {q.QuestionID}; ' вещи?
Вы вызываете .ToString () для matchedques, что является перечислением:
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.
Попробуйте это:
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
, если ничего не найдено. Р>
Перейти на:
...
var matchedques = from q in dc.GetTable<Question>()
where q.QuestionText.Contains(quesText)
select q.QuestionID;
например ,удалите new {...}, таким образом, вы создаете новый тип anonimouse со свойством id.