代码之家  ›  专栏  ›  技术社区  ›  Vaccano

如何懒惰地加载有列表支持的我自己的IQueryable

  •  4
  • Vaccano  · 技术社区  · 14 年前

    我有这样定义的权限列表:

    private List<PermissionItem> permissionItems;
    private ReadOnlyCollection<PermissionItem> permissionItemsReadOnly;
    

    此列表是通过后台线程从web服务中检索的。只读版本是从列表版本中填充的。

    我将此列表公开给我的(相当大的)应用程序的其余部分,如下所示:

    public IQueryable<PermissionItem> PermissionItems
    {
       get
       {
           // Make sure that the permissions have returned.  
           // If they have not then we need to wait for that to happen.
           if (!doneLoadingPermissions.WaitOne(10000))
               throw new ApplicationException("Could not load permissions");
    
           return permissionItemsReadOnly.AsQueryable();
       }
    }
    

    这一切都很好。用户可以请求权限,并在加载后获取权限。

    但如果我在构造函数中(在不同的类中)有这样的代码:

    ThisClassInstanceOfThePermisssions = SecurityStuff.PermissionItems;
    

    然后我很确定,在权限返回之前,它将被阻止。但在实际使用权限之前,它不需要阻止。

    我读过IQueryable是“懒惰加载”。(我在实体框架代码中使用了此功能。)

    有没有办法改变这一点,允许在任何时候引用我的IQueryable,并且只在实际使用数据时阻止?

    注意:这是一个“很好拥有”的功能。实际上,加载权限并不需要太长时间。所以,如果这是一个“滚动你自己”的查询/表达式的东西,那么我可能会通过。但我很好奇需要什么才能使它工作。

    2 回复  |  直到 14 年前
        1
  •  5
  •   usr    14 年前

    是的,这是可能的。首先,您可能应该切换到IEnumerable,因为您没有使用任何IQueryable功能。接下来,您需要实现一个新的迭代器:

    public IEnumerable<PermissionItem> PermissionItems
    {
       get
       {
            return GetPermissionItems();
       }
    }
    static IEnumerable<PermissionItem> GetPermissionItems()
    {
           // Make sure that the permissions have returned.  
           // If they have not then we need to wait for that to happen.
           if (!doneLoadingPermissions.WaitOne(10000))
               throw new ApplicationException("Could not load permissions");
    
           foreach (var item in permissionItemsReadOnly) yield return item;
    }
    

    只有当属性的调用方枚举 IEnumerable 。只是退货没有任何作用。

        2
  •  1
  •   oleksii    14 年前

    看看 Lazy<T>

    在第一次 Lazy.Value 所有物 被访问。使用Lazy的实例推迟创建 大型或资源密集型对象,或执行 资源密集型任务