能否将azure表存储IQueryable(table.CreateQuery())公开为POCO?

能否将azure表存储IQueryable(table.CreateQuery())公开为POCO?,azure,repository,azure-storage,azure-table-storage,Azure,Repository,Azure Storage,Azure Table Storage,我有一个包含30多个项目的大型应用程序,目前使用IRepository和POCO实体。我想知道是否有一种不用实现ITableEntity就可以使用表存储的方法。我不想将azure storage nugget包导入每个项目,并将所有实体更改为使用ITableEntity 实体适配器 我知道可以创建一个实体适配器(如下所示),它在读取或写入单个实体时工作得非常好。但在尝试通过table.CreateQuery()公开IQueryable时,我无法实现这一点 公共类AzureEntity { 公共G

我有一个包含30多个项目的大型应用程序,目前使用IRepository和POCO实体。我想知道是否有一种不用实现ITableEntity就可以使用表存储的方法。我不想将azure storage nugget包导入每个项目,并将所有实体更改为使用ITableEntity

实体适配器

我知道可以创建一个实体适配器(如下所示),它在读取或写入单个实体时工作得非常好。但在尝试通过table.CreateQuery()公开IQueryable时,我无法实现这一点

公共类AzureEntity
{
公共Guid Id{get;set;}
公共字符串分区键{get;set;}
公共字符串行键{get;set;}
公共DateTimeOffset时间戳{get;set;}
公共字符串ETag{get;set;}
}
内部类AzureStorageEntityAdapter:ITableEntity,其中T:AzureEntity,new()
{
#区域属性
/// 
///获取或设置实体的分区键
/// 
公共字符串分区键
{
获取{return InnerObject.PartitionKey;}
设置{InnerObject.PartitionKey=value;}
}
/// 
///获取或设置实体的行键。
/// 
公共字符串行键
{
获取{return InnerObject.RowKey;}
设置{InnerObject.RowKey=value;}
}
/// 
///获取或设置实体的时间戳。
/// 
公共日期时间偏移时间戳
{
获取{return InnerObject.Timestamp;}
设置{InnerObject.Timestamp=value;}
}
/// 
///获取或设置实体的当前ETag。
///将此值设置为“*”,以便在更新操作中盲目覆盖实体。
/// 
公共字符串ETag
{
获取{return InnerObject.ETag;}
设置{InnerObject.ETag=value;}
}
/// 
///原实体的席位持有人
/// 
公共T InnerObject{get;set;}
#端区
#区域导体
公共AzureStorageEntityAdapter()
{
//如果您想处理没有默认构造函数的对象,可以使用(T)Activator.CreateInstance(typeof(T));
this.InnerObject=new T();
}
公共AzureStorageEntityAdapter(T innerObject)
{
this.InnerObject=InnerObject;
}
#端区
#区域方法
公共虚拟void ReadEntity(IDictionary属性,OperationContext OperationContext)
{
TableEntity.ReadUserObject(this.InnerObject、properties、operationContext);
}
公共虚拟IDictionary写入权限(OperationContext OperationContext)
{
返回TableEntity.WriteUserObject(this.InnerObject,operationContext);
}
#端区
}
我希望能够做这样的事情

public class TableStorageRepository : IRepository
{
    // snip...

    public IQueryable<T> FindAll<T>() where T : class, new()
    {
        CloudTable table = GetCloudTable<T>();
        return table.CreateQuery<AzureStorageEntityAdapter<T>>();
    }

    // snip...
}
public类TableStorageRepository:IRepository
{
//剪断。。。
公共IQueryable FindAll(),其中T:class,new()
{
CloudTable=GetCloudTable();
return table.CreateQuery();
}
//剪断。。。
}
这里的问题是CreateQuery创建了一个

IQueryable<AzureStorageEntityApater<T>>.
IQueryable。
我不知道如何获得所有“内部对象”的IQueryable


有人知道是否可以通过某种方式公开IQueryable而不公开ITableEntity吗?

这可能是您想要的,也可能不是您想要的,但可能会给您一些想法

我创建了一个基本存储库,并为每个实体使用了一个单独的存储库,负责传入正确的CloudTable、分区/行键/属性表达式和解析器。我以DynamicTableEntity为基础(它允许在我的实体中使用一些高级的东西,比如动态属性(比如小集合))

公共类基存储库
{
受保护的异步任务GetAsync(CloudTable表、表达式筛选器)
{
var query=table.CreateQuery().Where(filter.AsTableQuery();
var segment=wait query.ExecuteSegmentedAsync(null);
返回段.Results.FirstOrDefault();
}
受保护的异步任务GetAsync(CloudTable表、表达式筛选器、EntityResolver解析器)
{
var query=table.CreateQuery().Where(filter).Resolve(resolver);
var segment=wait query.ExecuteSegmentedAsync(null);
返回段.Results.FirstOrDefault();
}
受保护的异步任务GetAllAsync(CloudTable表,表达式筛选器,int take=1000)
{
如果(取数>10000)取数=10000;
如果(take<1)take=1;
var query=table.CreateQuery().Where(filter).Take(Take).AsTableQuery();
var token=新的TableContinuationToken();
var results=新列表();
while(令牌!=null)
{
var segment=wait query.ExecuteSegmentedAsync(令牌);
结果.添加范围(段.结果);
令牌=段.ContinuationToken;
}
返回结果;
}
受保护的异步任务GetAllAsync(CloudTable表、表达式筛选器、EntityResolver解析器、int take=1000)
{
如果(取数>10000)取数=10000;
如果(take<1)take=1;
var query=table.CreateQuery().Where(filter).Take(Take).Resolve(resolver);
var token=新的TableContinuationToken();
var results=新列表();
while(令牌!=null)
{
var segment=wait query.ExecuteSegmentedAsync(令牌);
结果.添加范围(段.结果);
令牌=段.ContinuationToken;
}
返回结果;
}
受保护的异步任务InsertAsync(CloudTable表、DynamicTableEntity)
{
尝试
{
var result=wait table.ExecuteAsync(TableOperation.Insert(entity));
返回result.HttpStatusCode;
}
捕获(StorageException-ex)
{
返回ex.RequestInformation.HttpStatusCode;
}
捕获(例外情况除外)
{
ret
IQueryable<AzureStorageEntityApater<T>>.
public class BaseRepository
{
    protected async Task<DynamicTableEntity> GetAsync(CloudTable table, Expression<Func<DynamicTableEntity, bool>> filter)
    {
        var query = table.CreateQuery<DynamicTableEntity>().Where(filter).AsTableQuery();
        var segment = await query.ExecuteSegmentedAsync(null);
        return segment.Results.FirstOrDefault();
    }

    protected async Task<T> GetAsync<T>(CloudTable table, Expression<Func<DynamicTableEntity, bool>> filter, EntityResolver<T> resolver)
    {
        var query = table.CreateQuery<DynamicTableEntity>().Where(filter).Resolve(resolver);
        var segment = await query.ExecuteSegmentedAsync(null);
        return segment.Results.FirstOrDefault();
    }

    protected async Task<IEnumerable<DynamicTableEntity>> GetAllAsync(CloudTable table, Expression<Func<DynamicTableEntity, bool>> filter, int take = 1000)
    {
        if (take > 10000) take = 10000;
        if (take < 1) take = 1;

        var query = table.CreateQuery<DynamicTableEntity>().Where(filter).Take(take).AsTableQuery();
        var token = new TableContinuationToken();
        var results = new List<DynamicTableEntity>();
        while (token != null)
        {
            var segment = await query.ExecuteSegmentedAsync(token);
            results.AddRange(segment.Results);
            token = segment.ContinuationToken;
        }
        return results;
    }

    protected async Task<IEnumerable<T>> GetAllAsync<T>(CloudTable table, Expression<Func<DynamicTableEntity, bool>> filter, EntityResolver<T> resolver, int take = 1000)
    {
        if (take > 10000) take = 10000;
        if (take < 1) take = 1;

        var query = table.CreateQuery<DynamicTableEntity>().Where(filter).Take(take).Resolve(resolver);
        var token = new TableContinuationToken();
        var results = new List<T>();
        while (token != null)
        {
            var segment = await query.ExecuteSegmentedAsync(token);
            results.AddRange(segment.Results);
            token = segment.ContinuationToken;
        }
        return results;
    }

    protected async Task<int> InsertAsync(CloudTable table, DynamicTableEntity entity)
    {
        try
        {
            var result = await table.ExecuteAsync(TableOperation.Insert(entity));
            return result.HttpStatusCode;
        }
        catch (StorageException ex)
        {
            return ex.RequestInformation.HttpStatusCode;
        }
        catch (Exception ex)
        {
            return 500;
        }
    }

    protected async Task<int> ReplaceAsync(CloudTable table, DynamicTableEntity entity)
    {
        try
        {
            var result = await table.ExecuteAsync(TableOperation.Replace(entity));
            return result.HttpStatusCode;
        }
        catch (StorageException ex)
        {
            return ex.RequestInformation.HttpStatusCode;
        }
        catch (Exception ex)
        {
            return 500;
        }
    }

    protected async Task<int> DeleteAsync(CloudTable table, DynamicTableEntity entity)
    {
        try
        {
            var result = await table.ExecuteAsync(TableOperation.Delete(entity));
            return result.HttpStatusCode;
        }
        catch (StorageException ex)
        {
            return ex.RequestInformation.HttpStatusCode;
        }
        catch (Exception ex)
        {
            return 500;
        }
    }

    protected async Task<int> MergeAsync(CloudTable table, DynamicTableEntity entity)
    {
        try
        {
            var result = await table.ExecuteAsync(TableOperation.Merge(entity));
            return result.HttpStatusCode;
        }
        catch (StorageException ex)
        {
            return ex.RequestInformation.HttpStatusCode;
        }
        catch (Exception ex)
        {
            return 500;
        }
    }
}
// method
public Task<IEnumerable<T>> GetAllAsync<T>(string pk1, string pk2, EntityResolver<T> resolver, int take = 1000, Expression<Func<DynamicTableEntity, bool>> filterExpr = null)
    {
        var keysExpr = x => x.PartitionKey.Equals(string.Format("{0}_{1}", pk1, pk2);
        var queryExpr = filterExpr != null ? keysExpr.AndAlso(filterExpr) : keysExpr;
        return base.GetAllAsync<T>(CloudTableSelector.GetTable(), queryExpr, resolver, take);
    }

// call
var products = await ProductRepo.GetAllAsync<ProductOwnerViewDto>(orgType, orgId, ProductOwnerViewDto.GetResolver(), take, x => x.RowKey.CompareTo(fromId) > 0);