C# 使用表达式组合具有不同签名的函数

C# 使用表达式组合具有不同签名的函数,c#,expression-trees,C#,Expression Trees,我使用以下类包装一些DocumentDB访问,它允许我在同一集合中存储多个实体: public class TypedEntity<T> { public string Type { get; set; } public T Item { get; set; } public TypedEntity(T item) { Id = Guid.NewGuid().ToString(); Item = item;

我使用以下类包装一些DocumentDB访问,它允许我在同一集合中存储多个实体:

public class TypedEntity<T> {
    public string Type { get; set; }

    public T Item { get; set; }

    public TypedEntity(T item) {
        Id = Guid.NewGuid().ToString();
        Item = item;
        Item.Id = Id;
        Type = typeof (T).FullName;
    } 
}
公共类类型身份{
公共字符串类型{get;set;}
公共T项{get;set;}
公共类型标识(T项){
Id=Guid.NewGuid().ToString();
项目=项目;
项目Id=Id;
Type=typeof(T).全名;
} 
}
此类的用法封装在存储库类中。我正在尝试构建repository类的API,这样消费者就不需要知道
TypedEntity
的用法,而是可以将其作为
的源代码。例如,存储库有一个具有此签名的方法:

public async Task<IQueryable<T>> WhereAsync(Func<T, bool> predicate)
公共异步任务同步(Func谓词)
为了实际检索此数据,谓词需要与与
TypedEntity
交互的谓词组合/转换。这是我在脑海中描绘的我最终想要实现的伪代码:

public async Task<IQueryable<T>> WhereAsync(Func<T, bool> predicate) {
    // remembering that dataSource is talking to a backing store of TypedEntity<T>
    var queryable = dataSource.Where(x => x.Type == typeof(T).FullName && predicate(x.Item));
   // ... other business logic stuff
}
公共异步任务同步(Func谓词){
//请记住,数据源正在与TypedEntity的备份存储进行通信
var queryable=dataSource.Where(x=>x.Type==typeof(T.FullName&&predicate(x.Item));
//…其他业务逻辑的东西
}

这实际上会生成一个表达式,但最终会导致在传入谓词(DocumentDb无法理解)周围使用.Invoke。是否有某种方法可以将类型部分与传入的Func组合起来,以手动构建表达式?

您将希望采用
表达式而不仅仅是
Func
。然后,在执行
Select()
投影之后,在
Where()
子句中应用它应该相当容易:

public async Task<IQueryable<T>> WhereAsync(Expression<Func<T, bool>> predicate) {
    // remembering that dataSource is talking to a backing store of TypedEntity<T>
    var typeName = typeof(T).FullName;
    var queryable = dataSource.Where(x => x.Type == typeName)
        .Select(x => x.Item)
        .Where(predicate);
   // ... other business logic stuff
}
公共异步任务同步(表达式谓词){
//请记住,数据源正在与TypedEntity的备份存储进行通信
var typeName=typeof(T).FullName;
var queryable=dataSource.Where(x=>x.Type==typeName)
.选择(x=>x.Item)
.Where(谓语);
//…其他业务逻辑的东西
}