LazyList与 System.Lazy> 比较在 ASP.NET MVC 2 中?

发布于 2024-08-30 04:57:45 字数 672 浏览 10 评论 0 原文

在 Rob Conery 的 Storefront 系列中,Rob 广泛使用 LazyList<...> 构造从 IQueryables 中提取数据。

  • 这与 .NET 4.0(也许更早)中现在可用的 System.Lazy<...> 构造有何不同?

基于 DoctaJones 的精彩答案的更多深度:

  1. 如果我想将 IQueryable 作为 List 进行操作,您会推荐其中一个吗? ?
    我假设既然 Lazy 现在已经在框架中,那么对于未来的支持和可维护性来说,这是一个更安全的选择?
  2. 如果我想使用强类型而不是匿名 (var) 类型,以下语句在功能上是否等效?
    • Lazy<列表<产品>>>产品 = new Lazy>();
    • LazyList<产品>; = new LazyList();

In Rob Conery's Storefront series, Rob makes extensive use of the LazyList<..> construct to pull data from IQueryables.

  • How does this differ from the System.Lazy<...> construct now available in .NET 4.0 (and perhaps earlier)?

More depth based on DoctaJones' great answer:

  1. Would you recommend one over the other if I wanted to operate on IQueryable as a List<T>?
    I'm assuming that since Lazy<T> is in the framework now, it is a safer bet for future support and maintainability?
  2. If I want to use a strong type instead of an anonymous (var) type would the following statements be functionally equivalent?
    • Lazy<List<Products>> Products = new Lazy<List<Product>>();
    • LazyList<Product> = new LazyList<Product>();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

捎一片雪花 2024-09-06 04:57:45

LasyList 仅适用于 IQueryable 源。它是 IList 的实现,并通过填充包含指定 IQueryable 的所有结果的私有列表。第一次访问任何 IList 时都会进行初始化。成员。

示例用法为

var myList = new LazyList(products.Where(p => p.Name.StartsWith("T"));
//initialization occurs here
Console.Write(myList.Count);

System.Lazy 类适用于任何类型并且不限于IQueryable。第一次使用 Lazy.Value 属性时会发生延迟初始化被访问。

示例用法是

var lazyString = new Lazy(() => "Hello world");
//initialization occurs here
Console.Write(lazyString.Value);

我们可以重写 LazyList使用 Lazy 的示例如下:

var myList = new Lazy(() => products.Where(p => p.Name.StartsWith("T").ToList());
//initialization occurs here
Console.Write(myList.Value.Count);

简而言之: LazyList;仅适用于 IQueryable、Lazy;适用于任何类型。

LazyList适用于当您想要 IQueryable 的结果时的特定用例。作为 List,但您不希望在使用它之前进行评估。


更新回答扩展问题:

如果我想将 IQueryable 作为 List 进行操作,您会推荐其中一个吗?
我假设自从 Lazy现在已经在框架中了,对于未来的支持和可维护性来说这是一个更安全的选择?

就我个人而言,我也不会使用。如果您有 IQueryable,我会将其保留为 IQueryable 以最大限度地提高您的灵活性。通过保留 IQueryable,您仍然可以访问 LINQ to SQL 的查询理解(只要上下文仍然存在)。

例如,如果您在 IQueryable 上调用 .ToList(),您将要求 LINQ to SQL 从目标表中选择所有列,并合并所有结果(这可能非常昂贵,特别是如果您有数千个结果)。这将被翻译为“SELECT * FROM MyTable”之类的内容。

如果您在 IQueryable 上调用 .Count(),则要求 LINQ to SQL 仅获取结果数,这将被转换为类似“SELECT COUNT(*) FROM MyTable”的内容。这样做比合并所有结果然后计算它们要有效得多,特别是如果您只对数字感兴趣的话!

通过在 IQueryable 上使用 .Where(),LINQ to SQL 会将条件添加到 SQL 查询中的 WHERE 子句。这意味着您只会从 SQL 中提取您感兴趣的数据,而不是对您无意使用的结果进行水合。

您会发现,通过保留 IQueryable,您可以使事情变得更加灵活。大多数时候,它会给你带来比水合整个结果集更好的性能。

如果我想使用强类型而不是匿名 (var) 类型,以下语句在功能上是否等效?

Lazy<List<Product>> products = new Lazy<List<Product>>(); 
LazyList<Product> products = new LazyList<Product>();

我认为您将匿名类型与隐式类型混淆了。使用 var 关键字声明的变量是隐式类型的,以匹配分配给它的类型。它是强类型的,因此在初始分配后无法更改。

这两个语句在功能上并不等同。 LazyList<产品>是 IList,而 Lazy> 是 IList。是包含 List 的包装器。因为您对在惰性评估列表上进行操作特别感兴趣,所以我认为 LazyList可能更适合您的目的。

您应该问问自己是否真的需要实际的产品列表。如果没有令人信服的理由需要一个实际的列表,我会坚持使用 IQueryable。

The LasyList<T> only works with an IQueryable<T> source. It is an implementation of IList<T> and works by populating a private List with all results from the specified IQueryable<T>. The initialization occurs the first time you access any of the IList<T> members.

Example usage would be

var myList = new LazyList(products.Where(p => p.Name.StartsWith("T"));
//initialization occurs here
Console.Write(myList.Count);

The System.Lazy<T> class works with any type and is not limited to IQueryable<T>. Lazy initialization occurs the first time the Lazy<T>.Value property is accessed.

Example usage would be

var lazyString = new Lazy(() => "Hello world");
//initialization occurs here
Console.Write(lazyString.Value);

We could rewrite the LazyList<T> example to use Lazy<T> as follows:

var myList = new Lazy(() => products.Where(p => p.Name.StartsWith("T").ToList());
//initialization occurs here
Console.Write(myList.Value.Count);

In short: LazyList<T> only works with IQueryable<T>, Lazy<T> works with any type.

LazyList<T> is for the specific use case of when you want the results of an IQueryable<T> as a List<T>, but you don't want the evaluation to occur until you use it.


UPDATE to answer expanded question:

Would you recommend one over the other if I wanted to operate on IQueryable as a List<T>?
I'm assuming that since Lazy<T> is in the framework now, it is a safer bet for future support and maintainability?

Personally I wouldn't use either. If you've got an IQueryable I would keep it as an IQueryable to maximise your flexibility. By keeping the IQueryable you still get access to LINQ to SQL's query comprehension (as long as the context is still alive).

For example, if you call .ToList() on an IQueryable you are asking LINQ to SQL to select all of the columns from the target table and hydrate all of the results (this could be very expensive, especially if you've got thousands of results). This will get translated to something like "SELECT * FROM MyTable".

If you call .Count() on the IQueryable you are asking LINQ to SQL to just get the number of results, this will get translated to something like "SELECT COUNT(*) FROM MyTable". Doing this is much more efficient than hydrating all of the results and then counting them, especially if you're only interested in the number!

By using .Where() on the IQueryable LINQ to SQL will add your conditions to the WHERE clause in the SQL query. This means that you will only pull the data from SQL that you're interested in, rather than hydrating results that you have no intention of using.

You see, by keeping the IQueryable you make things much more flexible for yourself. The majority of the time it will give you better performance than hydrating the entire result set.

If I want to use a strong type instead of an anonymous (var) type would the following statements be functionally equivalent?

Lazy<List<Product>> products = new Lazy<List<Product>>(); 
LazyList<Product> products = new LazyList<Product>();

I think you're getting anonymous typing confused with implicit typing. A variable declared using the var keyword is implicitly typed to match the type that is being assigned to it. It is strongly typed and therefore cannot be changed after the initial assignment.

The two statements are not functionally equivalent. The LazyList<Product> is an IList<Product>, wheras the Lazy<List<Product>> is a wrapper that contains a List<Product>. Because you're specifically interested in operating on a lazy evaluated list, I'd say the LazyList is probably more specific for your purposes.

You should ask yourself if you really need an actual List of products. If there isn't a compelling reason for having an actual List I'd stick with the IQueryable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文