使用表达式将Func与不同的签名

时间:2015-06-05 21:51:05

标签: 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;
        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
}

这实际上构建但最终导致一个Expression使用.Invoke围绕传入的谓词(DocumentDb无法理解)。有没有什么方法可以将类型部分与传入的Func结合起来手动构建表达式?

1 个答案:

答案 0 :(得分:3)

您想要接受Expression<>而不仅仅是Func<>。然后,在您执行Where()投影后,在Select()子句中应用它应该相当容易:

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
}