我有一个linq查询,它根据问题文本返回问题的ID。 然后,需要使用此ID将日期表中的日期与该特定问题相关联。问题已经存储,日期存储在不同的时间。
问题是查询将questionID作为匿名类型返回,因此当我需要将该questionID指定为另一个表中的questionID时,它会抛出一个错误,指出该表正在期待一个Guid。在此之后,我将匿名类型转换为字符串,然后使用GUID转换功能将字符串转换为GUID,但现在它给出了GUID应为32个字符和4个破折号的错误。
我对此的想法是,匿名类型将questionID返回为“QuestionID = jkj939-89239829- etc etc.” - 使用前面的字符前缀,因此在将其转换为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;
}
}
答案 0 :(得分:4)
除非我遗漏了什么,为什么不只是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());
}
显然,这个问题比我最初想的还要多。在回复评论时,请记住,您在匹配项中返回枚举结果(因此上面的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 :(得分:1)
为什么不只是select q.QuestionID;
而不是这个`select new {q.QuestionID};'东西?
答案 2 :(得分:1)
你在匹配的地方调用.ToString(),这是一个枚举:
var matchedques = from q in dc.GetTable<Question>()
where q.QuestionText.Contains(quesText)
select new{
q.QuestionID
};
string qidGuidString = matchedques.ToString();
因此,在上面的示例中,匹配项是匿名类型的一种实现(您应该取消它并直接选择q.QuestionID)。在此调用ToString()将返回对象的字符串表示形式,而不仅仅是序列的第一个元素的QuestionId。
您是否期望上述查询始终只有一个结果?如果是这样,您应该查看Single运算符。
这样的事情应该做:
var matchedQuesId =
dc.GetTable<Question>()
.Where(q =>q.QuestionText.Contains(quesText))
.Single()
.QuestionID;
在这种情况下,您可以直接使用matchedQuesId。请注意,如果Where查询匹配none或多个元素,则会引发错误。阅读Single运算符以找出原因。
答案 3 :(得分:1)
试试这个:
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
var设置为对象的单个实例,而不是它们的枚举。当你知道你想要的只有一个值时,就可以享受一种享受。 OrDefault
位表示如果找不到任何内容,它将为NULL
。
答案 4 :(得分:-1)
更改为:
...
var matchedques = from q in dc.GetTable<Question>()
where q.QuestionText.Contains(quesText)
select q.QuestionID;
e.g。删除新的{...},这样您就可以使用id属性创建一个新的anonimouse类型。