C#Linq Guid匿名类型问题

时间:2009-05-05 09:17:20

标签: c# linq linq-to-sql guid anonymous-types

我有一个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;
        }
    }

5 个答案:

答案 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类型。