我是Linq的新手。
我喜欢这个简单的lambda表达式:
crmContext.CallForTags.FirstOrDefault(x => x.CallForText.Contains(callAgainForText)).RowID;
它会在一行中返回我想要的内容。
但是有类似的linq表达式:
crmContext.CallForTags.Where(x => x.CallForText.Contains(callAgainForText)).Select(x => x.RowID);
我希望这会做同样的事情并返回给我RowID
但它确实给我错误说:
无法将IQueryable隐式转换为int
我试着在网上搜索。但是找不到类似的帖子??
任何人都可以帮助我理解,它有何不同? 两个之间是否有任何性能开销? 关于绩效,哪一种方法更好?
答案 0 :(得分:2)
Select
会返回IEnumerable<T>
。如果只有一个元素,它将返回带有一个元素的IEnumerable<T>
。
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.select.aspx
FirstOrDefault
返回T的单个实例。
http://msdn.microsoft.com/en-us/library/system.linq.enumerable.firstordefault.aspx
使用您的第一个查询,您说“给我CallForText
包含值callAgainForText
的第一行的RowID(如果不存在,则为类型的默认值)。”
使用第二个查询,您实际上是在说“为CallForText
包含callAgainForText
的值的每一行提供RowID”。这将始终返回IEnumerable
,即使它只包含一个项目。
然后,您尝试将此查询的结果(返回多个项目)分配给单个T实例,这当然不起作用。
答案 1 :(得分:1)
这部分将为您提供完整的一行
//some IQueryable = crmContext.CallForTags.Where(x => x.CallForText.Contains(callAgainForText));
现在因为你使用select来获得单列的值然后尝试将它带入一个像上面的int变量,因为它返回一个IEnumerable
Int32 test = crmContext.CallForTags.Where(x => x.CallForText.Contains(callAgainForText)).RowID;
当您使用where
然后column name
时,它会提供一个值,或FirstorDefault()
代表完整的行。
FirstOrDefault返回与条件匹配的第一个元素,或者为null。
答案 2 :(得分:0)
当你使用select时,返回你在lambda表达式中指定的元素的IEnumerable,SingleOrDefault或FirstorDefault将返回实际类型而不是它的可枚举类型。
答案 3 :(得分:0)
在第一个表达式中,如果有任何结果并且访问其RowID
属性(可能NullReferenceException
那里),则要求仅返回一个结果,我假设它是int
类型。
在第二个表达式中,您要求根据条件过滤列表,然后要求检索结果中每个项目的RowID
属性。我假设您要将其分配给int类型的变量,这需要从IQueryable
到int
的隐式转换,因此是错误。
答案 4 :(得分:0)
假设RowID
是一个int,那么:
crmContext.CallForTags.FirstOrDefault(x => x.CallForText.Contains(callAgainForText)).RowID
将返回一个int,即RowID。但是,如果序列为空,FirstOrDefault()
将为引用类型返回null,这意味着当您尝试在此情况下取消引用.RowID
时,它将抛出NullReferenceException。
crmContext.CallForTags.Where(x => x.CallForText.Contains(callAgainForText)).Select(x => x.RowID);
将返回与谓词RowID
匹配的所有项的所有x.CallForText.Contains(callAgainForText)
值的序列。
注意这是一个序列,而不是一个int! (按“序列”我的意思是IEnumerable<T>
。)
答案 5 :(得分:0)
FirstOrDefault
返回与谓词匹配的第一个元素,或者为null(如果未找到匹配项)。返回类型将是int
(如果谓词返回true),因为您只选择first
元素,或者如果谓词返回false,则返回null
。
rmContext.CallForTags.Where(x => x.CallForText.Contains(callAgainForText)).Select(x => x.RowID);
Selects包含callAgainForText
并返回IEnumerable of integers (Which are the Row ID's) or more specifically IEnumerable<int>