繁体   English   中英

链接AsEnumerable和AsQueryable是否安全?

[英]Is it safe to chain AsEnumerable and AsQueryable?

我有一个可以同时在IEnumerableIQueryable上运行的扩展方法。 该方法解析输入并最后调用Skip().Take()

public static IEnumerable<T> SelectRange<T>(
    this IEnumerable<T> target,
    RangeHeaderValue range
    )

此方法适用于IQueryable但返回IEnumerable 因此,我添加了另一个要转换的方法,调用第一个方法并再次进行转换:

public static IQueryable<T> SelectRange<T>(
    this IQueryable<T> target,
    RangeHeaderValue range
    )
{
    return target.AsEnumerable().SelectRange(range).AsQueryable();
}

这样进行链式转换安全吗? 我担心它可能会干扰IQueryable提供程序,而是在内存中的集合上运行该方法。 我了解延迟/急切加载的基本知识,但这是一个相当复杂的主题,我不想仅仅假设它会起作用。


注意:关于链接的危险,可接受的答案是正确的,但是我想补充一点,实现IQueryable方法并从IEnumerable方法中调用它(以便简单地进行切换)是安全的。

没有; 那不是一个好主意。

调用AsEnumerable()将实现整个查询,然后在客户端上运行Skip()Take()

您需要为该方法创建一个单独的(且相同的)版本,该版本采用并返回IQueryable<T> ,后者仅调用Queryable方法,以便查询可以在服务器上运行。

简短的答案: 也许

AsEnumerable() 可能会实现您的查询。 最简单的查找方法是获取SQL Server Express Profiler并排进行调试,以查看何时准确调用查询。 实际上, IQueryable继承自IEnumerable

此外,在调试时:如果尝试查看发生了什么,则IDE可能会实现它,以在漂亮的VS浮动GUI调试工具中显示它

以我的经验:在我调用ToArray()ToList()或从ICollection继承的任何其他方法之前,从AsEnumerable()AsQueryable()来回实现不会实现,但是请记住IQueryable会将计算保持在类似于图的内存。 因此,即使您实际上看不到它正在查询数据库,在内存不足的情况下,您可能仍会付出一定的性能代价。

与您一样,我试图避免在“ 存储库模式”中生成重复,特别是在分页时:

public static class Paginate
{
    public static IEnumerable<T> Enumerable<T>(int records, int iPage, IEnumerable<T> input) where T : class { return input.Skip(records * iPage).Take(records); }

// My internal OCD hates this dup >.o
    public static IQueryable <T> Queryable <T>(int records, int iPage, IQueryable <T> input) where T : class { return input.Skip(records * iPage).Take(records); }
}

但我最终还是这样做了,以防万一我避免遇到一个问题,该问题会使我整个早晨都陷入混乱,追逐一个被上帝抛弃的错误,最后面对一个死胡同,面对着贴在墙上的留言条,说: “我告诉你如此”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM