正确定义 IQueryable<TSource>.OrderBy( ) 类方法的语法

Correct syntax to define an IQueryable<TSource>.OrderBy( ) like method

我需要创建一个扩展方法来检查我需要为数据库 table 查询做的检查。对于模型中的不同 table,我需要在 MVC 应用程序的所有控制器中执行该检查。这就是为什么我想将代码集中在扩展方法中。

为了让你理解上下文,我将使用一个虚构的简化案例来解释。

假设我有两个名为 ATableBTable 的 Db 实体。两者都与 Company table.

有关

在正常情况下,我使用此代码按公司条件进行筛选:

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 作为唯一的 属性 并在 ATableBTable 类。这样我创建了这个方法:

    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;
    }

至少编译通过了,但是在运行时抛出异常,因为 ICompany 不被 Linq 识别。

我的下一次尝试可能是创建一个类似于 OrderBy 扩展方法的方法,但我不知道定义它的正确语法。

我做了类似的事情:

public static IQueryable<TSource> CheckByCompany<TSource, Company>(this IQueryable<TSource> source, Expression<Func<TSource, Company>> company)

但是,那之后,我该如何使用呢?该方法签名正确吗?

我看到了 OrderBy 扩展方法的源代码,但它并不容易理解。

有什么建议吗?

海梅

最后我实现了本页提到的解决方案: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;
    }

它有效,但是,我想知道性能如何。你有什么意见吗?

问候 海梅