【发布时间】:2020-05-19 15:58:51
【问题描述】:
我需要创建一个扩展方法来检查我需要对数据库表查询进行的检查。对于模型中的不同表,我需要在 MVC 应用程序的所有控制器中进行检查。这就是为什么我想将代码集中在一个扩展方法中。
为了让你理解上下文,我将使用一个发明和简化的案例来解释。
假设我有两个名为 ATable 和 BTable 的 Db 实体。两者都与Company 表有关系。
在正常情况下,我使用此代码按公司条件进行过滤:
var queryA = db.ATable.where(a => a.Company.IsEnabled)
var queryB = db.BTable.where(b => b.Company.IsEnabled)
条件比这更复杂,但通过这个简化的案例就很清楚了。
我的想法是这样称呼:
var queryA = db.ATable.CheckByCompany(a => a.Company);
var queryB = db.BTable.CheckByCompany(b => b.Company);
也就是说,仅使用相关属性调用方法,并且该方法将负责在该属性上创建整个条件。这种调用方式类似于OrderBy 扩展方法,所以我想我可以做类似的事情。
我的第一次尝试是创建一个名为ICompany 的接口,其中Company 作为唯一的属性,并在ATable 和BTable 类中实现它。这样我就创建了这个方法:
public static IQueryable<TSource> CheckByCompany<TSource>(this IQueryable<TSource> source)
where T: ICompany
{
if (source == null)
throw new ArgumentNullException();
IQueryable<TSource> query = source.Where(t => source.Company.IsEnabled);
// The rest of the conditions I need for Company entity.
return query;
}
至少可以编译,但在运行时抛出异常,因为 Linq 无法识别 ICompany。
我的下一个尝试可能是创建一个类似于 OrderBy 扩展方法的方法,但我不知道定义它的正确语法。
我做了类似的事情:
public static IQueryable<TSource> CheckByCompany<TSource, Company>(this IQueryable<TSource> source, Expression<Func<TSource, Company>> company)
但是,在那之后,我该如何使用它?那个方法签名正确吗?
我看到了 OrderBy 扩展方法的源代码,但是不太容易理解。
有什么建议吗?
詹姆
【问题讨论】:
-
我不太明白你想让你的
CheckByCompany做什么。如果我传入a => a.Company,它将变成Where(a => a.Company.IsEnabled)调用。我可以在那里传递哪些其他 lambda 表达式? -
条件比这复杂得多。它也是根据网页中存在的一些变量动态构建的。模型中的所有表都与公司实体相关,并且在 MVC 应用程序的每个控制器中多次调用该条件。如果由于某种原因,该条件发生了变化,我将需要多次更改它,并有可能出错。如果是这样的话,在一处修改条件会更容易。
-
你还没有回答我的问题?...听起来除了
a => a.Company之外,您不会传递其他任何东西...那为什么还有参数呢? -
对不起,你是对的。我只会将
a.Company传递给扩展方法。
标签: c# linq lambda entity-framework-6 extension-methods