我有一个像这样的界面......
public interface IAccountRepository : IDisposable {
IQueryable<Account> FindByUserId(int userId); //here, Resharper says "Return type can be IEnumerable<Account>"
}
但Resharper建议我改为IEnumerable<Account> FindByUserId(int userId)
。
为什么会这样?它不会强制将整个对象加载到内存中吗?我认为将执行推迟到真正需要对象之前会更好吗?
答案 0 :(得分:8)
这只是一般规则的具体实例。
如果要返回实现接口的类型SomeClass
或从其他类继承的类型,并且在整个解决方案中只使用返回对象的基类/接口中的方法(所以你不要使用SomeClass
中声明的任何方法,ReSharper将建议您将返回对象的类型替换为基类/接口的类型,以使代码更通用。
在这种情况下,您只使用IEnumerable<T>
派生的IQueryable<T>
接口的方法。
另请注意,这只是建议,而不是警告或错误。如果您愿意,可以放心地忽略它。
答案 1 :(得分:6)
答案是“不,但是”。
将其强制转换为IEnumerable不会强制执行。 IEnumerable空间中的运算符(如“Where”方法)仍然可以被懒惰地评估。
但这里有一些警告。如果您在此方法中开始使用LINQ运算符,那么LINQ将选择像GroupBy (IEnumerable)这样的Enumerable LINQ运算符,而不是像GroupBy (IQueryable)这样的Queryable运算符。请注意,它们的参数列表不同。
这样做的结果是您传递的Lambda表达式将转换为Func而不是Expression&gt; (注意两种方法的参数列表的差异)。因此,您的lambda将不是表达式树,这是Queryable源需要将其转换为SQL(或类似),以便查询可以通过服务器和服务器端执行。
因此,您的查询会更慢。不是因为它会在你投射后执行,而是因为一旦你开始尝试从中获取项目,整个数据源就会被转移到客户端。
当然,这只是在此方法中使用LINQ(附加“Where”子句或其他内容)时。如果你不这样做,你就没事了。
答案 2 :(得分:1)