如何使用由列表支持的我自己的IQueryable延迟加载

Vac*_*ano 4 .net c# iqueryable .net-4.0

我有一个如下定义的权限列表:

private List<PermissionItem> permissionItems;
private ReadOnlyCollection<PermissionItem> permissionItemsReadOnly;
Run Code Online (Sandbox Code Playgroud)

通过后台线程从Web服务检索此列表.只读版本从List版本填充.

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

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();
   }
}
Run Code Online (Sandbox Code Playgroud)

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

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

ThisClassInstanceOfThePermisssions = SecurityStuff.PermissionItems;
Run Code Online (Sandbox Code Playgroud)

然后我相当肯定会阻止,直到权限返回.但是在实际使用权限之前不需要阻止它.

我已经读过IQueryable是"Lazy Loading".(我在我的实体框架代码中使用了此功能.)

有没有办法可以改变它以允许随时引用我的IQueryable,并且只在实际使用数据时阻止?

注意:这是一个"很高兴"的功能.实际上加载权限不会花太长时间.所以,如果这是一个"滚动你自己的"查询/表达的东西,那么我可能会通过.但我很好奇它是如何使它工作的.

usr*_*usr 5

是的,这是可能的.首先,您可能应该切换到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;
}
Run Code Online (Sandbox Code Playgroud)

只有在属性的调用者枚举时,才会等待事件IEnumerable.回来它什么都不做.