我正在构建一个服务,该服务从各个存储库中检索类似Enum的实例。存储库以不同的方式存储数据,但是都可以将其检索到EnumEntry {int Id;字符串名称; }类。
我的想法是使用一个将Func委托作为选择器的基类,以标识每个基础存储库记录上的Id和Name字段。例如
// constructor:
BaseEnumService<T>(Table<T> table,
Expression<Func<T, int>> idSelector,
Expression<Func<T, string>> nameSelector) {... }
// usage
var caseCategoryService = new BaseEnumService(CaseCategoriesTable, x => x.id, x => x.category)
到目前为止一切顺利。
要检索EnumEntry,因为idSelector和nameSelector是纯函数的表达式,我认为我可以使用这样的lambda表达式,编译器会把它全部弄清楚:
table.Select(x => new EnumEntry() { Id = idSelector(x), Name = nameSelector(x) }).ToList();
...但是数据库IQueryable实现不满意,因为它不喜欢“外部”功能。
将所有内容与表达式树结合起来就可以了,例如
var record = Expression.Parameter(typeof(T));
Expression<Func<int, string, EnumEntry>> createEnumExpression = (id, name) => new EnumEntry() { Id = id, Name = name };
var selectExpression = Expression.Invoke(createEnumExpression,
Expression.Invoke(idSelector, record),
Expression.Invoke(nameSelector, record));
return table.Select(Expression.Lambda<Func<T, EnumEntry>>(selectExpression, record));
..但是对于如此简单的操作来说,这似乎很冗长和丑陋。
有没有办法像我最初尝试的那样使用lambda语法来组合Expression <>?