Linq用表达式查询抽象,哪种方式更好



我们一直在寻找一种很好的方法来查询我们的数据库,重点是易于开发,可读性和业务规则遵从性。

我在网上发现了两篇有趣的文章,它们描述了相似但略有不同的方法,一篇是使用查询对象和表达式,另一篇主要使用与业务相关的扩展方法,最终也使用了表达式。

  1. 查询对象方法
  2. 扩展方法方法

下面是一些示例代码,我们可以(在存储库中)用于这两种情况:

public IEnumerable<ControlOverview> GetRoutineControlOverviewsForTest(string testId, DateTime dateOfInterest)
    {
        var controlOverviewQuery = new ControlOverviewQuery()
                                           .ForTest(testId)
                                           .ForLotUsage(ControlLotUsageStatus.Routine)
                                           .ForControlStatusAt(dateOfInterest)
                                           .ForControlConfigurationAt(dateOfInterest)
                                           .ForControlLotConfigurableAt(dateOfInterest);
        return this.Context.ControlOverviews.Where(controlOverviewQuery.AsExpression());;
    }

第二个案例:

public IEnumerable<ControlOverview> GetRoutineControlOverviewsForTest(string testId, DateTime dateOfInterest)
    {
        return this.Context.ControlOverviews.ForTest(testId)
                                            .ForLotUsage(ControlLotUsageStatus.Routine)
                                            .ForControlStatusAt(dateOfInterest)
                                            .ForControlConfigurationAt(dateOfInterest)
                                            .ForControlLotConfigurableAt(dateOfInterest);
    }
如您所见,从开发人员的角度来看,这或多或少是相同的。可读性也是一样。唯一不同的是实现细节(扩展方法vs查询对象)

在我的团队中,对于使用哪种方法存在分歧,我找不到一组好的论据(赞成/反对)来支持一种方法或另一种方法。

我个人更喜欢第一种方法(查询对象),因为我是面向对象的家伙,喜欢它使用的构建器模式,但为了不使用扩展方法,我找不到比这更好的论据。我非常希望你能给我一些见解。也许这只是编码偏好很难或者说根本不可能用一个强有力的参数

说一个肯定比另一个好

在我看来,这些是重要的优点

查询方法

  • 由于方法实际上是类方法,因此它们可以访问内部,特别是可以限制访问。因此,您可以强制开发人员使用查询对象,而不是自定义LINQ。这确保了一致性和可维护性,但降低了灵活性
  • 您获得了使用多态性的灵活性。在您所链接的文章中,这并不是重点,但是一旦您开始使用不同的查询类实现(例如,使用不同模式
  • 对不同来源的数据进行统一访问),它就可能变得很重要。

扩展方法

  • 可以与接口一起使用。事实上,我最常使用扩展方法来实现接口的标准成员,我认为这是它们最有用的地方。然而,这只有在您有一些预定义的接口时才有意义,例如,在平台中已经可用,例如IQueryable。如果你使用的是你自己的类,你可以完全控制它,这一点是相当弱的。
  • 简洁性略好(我知道,不是那么多,但我想说这很重要)

我确实更喜欢第一种方法,因为它不会隐藏有IQueryable<>的事实(this.Context.ControlOverviews不是通过调用其他方法链"隐藏"),所以如果你想链一个额外的.Where()或额外的.Select(),很明显你可以做到。

相关内容

  • 没有找到相关文章

最新更新