我有一个简单的LINQ问题。我正在尝试查询列表并将成员ID与列表ID匹配,然后返回一些文本:
var IDtext = IDMethod(MembID);
var t = from ctext in cIDtext
where ctext.cid.ToString() == MembID
select cxt.C_ID;
ViewBag.thisID = t.ToString();
所有这一切都是:
System.Linq.Enumerable+WhereSelectArrayIterator`2[pu15.Models.C_ID,System.Int32]
但这永远不会改变或显示我希望它显示的内容。
我做错了什么?
答案 0 :(得分:7)
您想要使用Single
或SingleOrDefault
或First
或FirstOrDefault
,具体取决于您想要的内容,例如:
ViewBag.thisID = t.Single();
Single
将抛出异常。
如果您使用SingleOrDefault
,则会在多个结果或没有结果的情况下返回null
。
First
仅对空集合失败 - 当有多个元素时,它将返回第一个元素。
最宽容的FirstOrDefault
会返回null
表示空结果列表,第一个元素会返回。{/ p>
答案 1 :(得分:2)
您必须记住where
子句返回IEnumerable<T>
而不只是一个值。您必须获取该集合的第一个或特定元素并显示它,或者它是一个对象集合,显示该元素的属性。
在你的情况下,这将是:
var IDtext = IDMethod(MembID);
var allIDs = from ctext in cIDtext
where ctext.cid.ToString() == MembID
select cxt.C_ID;
var single = allIDs.SingleOrDefault();
//or:
var first = allIDs.FirstOrDefault();
ViewBag.thisID = single.ToString();
//or
ViewBag.thisID = first.ToString();
答案 2 :(得分:2)
您可以使用方法语法,跳过Where
子句,然后使用First()
ViewBag.thisID = cIDtext
.First(c => c.cid.ToString() == MembID)
.C_ID.ToString();
答案 3 :(得分:1)
t
是一个可以返回许多项的IEnumerable。如果您只想使用其中一项,则需要致电t.First()
或t.Single()
,例如:
ViewBag.thisID = t.First().ToString();
两种方法的区别在于,如果结果中有多个项目,Single
将抛出异常,而First
只会在没有匹配结果的情况下抛出。
如果您想检查结果是否确实存在,可以使用FirstOrDefault
或SingleOrDefault
,例如:
var id=t.FirstOrDefault();
if (id!=null)
ViewBag.thisID = id.ToString();
如果您将条件作为谓词传递给First
,FirstDefault
等,则可以压缩调用:
var id=cIDtext.FirstOrDefault(ctext=> ctext.cid.ToString() == MembID);
答案 4 :(得分:0)
问题是t
是IEnumerable
而ToString
只会为您提供该类型的名称。您需要将枚举转换为逗号分隔列表
ViewBag.thisID = string.Join(",", t.Select(v => v.ToString()));
或者您更有可能只需要一个值,而您需要使用First
或Single
。
ViewBag.thisID = t.First().ToString();
或
ViewBag.thisID = t.Single().ToString();
如果有多个返回值并且您只想要第一个,则使用First
,或者如果您想要最后一个,则可以使用Last
。如果查询只返回一个值,那么您应该使用Single
。还有FirstOrDefault
,LastOrDefault
和SingleOrDefault
,如果枚举为空,则返回默认值;如果枚举有多个值,则返回Single
。如果枚举为空,则Single
,First
和Last
将抛出异常,如果枚举具有多个值,则Single
将抛出异常。只需为您的用例选择合适的一个。