【发布时间】:2014-10-26 21:36:20
【问题描述】:
我的问题源于复杂的可重用逻辑规范。
我有以下Expression:
Expression<Func<User, bool>> userExp =
user => user.UserInRoles.Any(userInRole => userInRole.RoleId == SystemRoles.SysAdmin.Id);
我需要获得以下能力:
new CommonContext().Set<Estate>().Where(estate => userExp.WithParameter(estate.CreatorUser)).ToList();
那么如何将Estate 实体的Creator 传递到接受User 实体的表达式中,最后在linq to sql 中使用最终表达式?
问题是:WithParameter
编辑:
这个可行,但效率不高:
new CommonContext().Set<Estate>().ToList().Where(estate => userExp.Compile()(estate.CreatorUser)).ToList()
以下不是答案,因为Invoke method 无法转换为存储表达式:
Expression<Func<User, bool>> userExp =
user => user.UserInRoles.Any(userInRole => userInRole.RoleId == SystemRoles.SysAdmin.Id);
Expression<Func<Estate, User>> propAccessor = estate => estate.ApprovedByUser;
var estateParam = Expression.Parameter(typeof(Estate));
var userParam = Expression.Invoke(propAccessor, estateParam);
var translatedExp = Expression.Invoke(userExp, userParam);
var result = (Expression<Func<Estate, bool>>)Expression.Lambda(translatedExp, estateParam);
var exceptionProvider = new CommonContext().Set<Estate>().Where(result).ToList();
但我需要一些可以翻译成Store Expression的东西
也许最终的解决方案是分解然后重新组合表达式,如果是这样,我该如何封装它以便在类似情况下重用它? (因为这是我想要做的)
【问题讨论】:
-
如果你想创建过滤器来重用,你可以看看entityrestsdk.codeplex.com,在这个SDK中,我们一次性设置表达式,但是,你这样做的方式,它将难以调试和维护,因为您无法轻松地可视化您的过滤器。由于这些规则不会被动态重写,它们会在整个生命周期中保持不变,因此最好编写它们,因为它们看起来易于使用和测试。
标签: c# linq-to-sql expression