我有此代码Linq c#
from r in Employer.Restrictions
select new RestrictionDto(r);
雇主限制已注册,但从未调用RestrictionDto的构造函数,仅返回null。我在restrictionDto中放置了一个BreakPoint,并且代码永不停止。
我以前从未见过这个问题。我在代码中有很多类似的代码,并且工作正常。
有人可以帮忙吗?
答案 0 :(得分:5)
Linq查询是惰性的,也就是说,除非另行通知,否则它们实际上不会执行任何操作。
换句话说,您不是在要求执行查询。如果要执行查询,则必须以ToList
或您认为适合于手头任务的任何急切操作结束。
答案 1 :(得分:1)
您必须知道,LINQ语句有两种:
IEnumerable<...>
(或IQueryable)的人第一个组将仅返回一个对象,该对象包含枚举元素所需的所有内容:获取序列的第一个元素,一旦有了一个元素,就可以获取下一个,直到没有其他对象为止左。
注意:通过创建此可枚举的对象,您尚未枚举它。
第二组,不返回IEnumerable<...>
的LINQ函数实际上是将开始枚举的函数:ToList
,ToDictionary
,FirstOrDefault
,{{1 }},Count
,Max
。
这些函数使用输入Any
来调用IEnumerable
,并反复调用GetEnumerator()
直到知道返回值为止。通常,需要枚举完整的序列,有时只有其中的几个。
例如:
MoveNext()
返回您的问题
您的代码创建一个public static bool Any<TSource>(this IEnumerable<Tsource> source)
{
if (source == null) throw new ArgumentNullException(...);
IEnumerator<TSource> enumrator = source.GetEnumerator();
bool containsAnyElement = enumerator.MoveNext();
// no need to check the rest of the sequence, I already know the result:
return containsAnyElement;
}
,它类似于:
IEnumerable<...>
换句话说:创建一个可枚举的对象,对它进行枚举时,将为可枚举序列Employer.Restrictions中的每个限制返回一个新的对象RestrictionDto到在枚举器上调用的每个MoveNext。
因此,您已经创建了Enumerable对象,但尚未对其进行枚举。
尝试以下操作,调试器将向您显示RestrictionDto是实际创建的:
IEnumerable<RestrictionDto> restrictions = Employer.Restrictions
.Select(restriction => new RescrictionDto(restriction));
他们都将在内部做类似以下的事情:
var list = restrictions.ToList();
bool restrictionsAvailable = restrictions.Any();
var firstRestriction = restrictions.FirsOrDefault();
int numberOfRestrictions = restrictions.Count();
foreach (var restiction in restrictions)
{
...
}