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

本文关键字:函数 表达式 组合 | 更新日期: 2023-09-27 17:53:53

我使用下面的类来包装一些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;
    } 
}

该类的用法封装在一个存储库类中。我正在尝试构建存储库类的API,这样消费者就不需要知道TypedEntity<T>的使用情况,而可以将其视为<T>的源。例如,存储库有一个签名如下的方法:

public async Task<IQueryable<T>> WhereAsync(Func<T, bool> predicate)

为了实际检索该数据,需要将谓词与与TypedEntity<T>交互的谓词组合/转换。这是我在脑海中描绘的伪代码,是我最终想要实现的:

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
}

这实际上构建但最终导致在传入谓词周围使用. invoke的表达式(DocumentDb无法理解)。是否有一些方法,我可以将类型部分与传入的函数相结合,以手动建立表达式?

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

您将需要一个Expression<>而不仅仅是一个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
}