我使用以下类来包装一些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结合起来手动构建表达式?
答案 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
}