我需要创建一种扩展方法来进行数据库表查询所需的检查。对于模型中的不同表,该检查与我在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扩展方法的源代码,但遵循起来并不容易。
有什么建议吗?
Jaime
最后,我已经实现了此页面中提到的解决方案:https://codingsight.com/using-expressions-to-filter-data-of-database/
我最后的扩展方法是这样:
public static IQueryable<TSource> FiltraEmpresaCliente<TSource>(this IQueryable<TSource> source, ParentController controller, Expression<Func<TSource, Empresa>> empresa)
{
if (source == null)
throw new ArgumentNullException();
if (empresa == null)
throw new ArgumentNullException();
Expression<Func<TSource, bool>> filterValidity = entity => empresa.Call()(entity).Cliente.ClienteEliminadoEn == null && empresa.Call()(entity).Cliente.ClienteVigente && empresa.Call()(entity).EmpresaEliminadoEn == null && empresa.Call()(entity).EmpresaVigente;
Expression<Func<TSource, bool>> filterCustomer = null;
Expression<Func<TSource, bool>> filterCompany = null;
var empresaId = controller.EmpresaID;
if (empresaId > 0)
filterCompany = entity => empresa.Call()(entity).EmpresaId == empresaId;
var clienteId = controller.ClienteID;
if (clienteId > 0)
filterCustomer = entity => empresa.Call()(entity).ClienteId == clienteId;
IQueryable<TSource> query = source.Where(filterValidity.SubstituteMarker());
if (filterCompany != null)
query = query.Where(filterCompany.SubstituteMarker());
if (filterCustomer != null)
query = query.Where(filterCustomer.SubstituteMarker());
return query;
}
但是,我想知道性能如何。你有什么意见吗?
关于海梅