封装不同存储库的LINQ查询以避免重复代码

时间:2015-10-28 02:32:37

标签: c# linq

我的app中实际上有这个树方法:

public decimal GetPayrunAllowanceYTDValue(Guid employeeId, Guid payrunId, Guid payItemId, DateTime paymentDate)
{
    var payrunPayItem = _firstRepository.FilterBy(x => x.EmployeeId == employeeId
                                                    && x.PayrunsId != payrunId
                                                    && x.PayItemId == payItemId
                                                   && x.EffectiveDate <= paymentDate, null)
                    .OrderByDescending(x => x.EffectiveDate).FirstOrDefault();
         return payrunPayItem.YTD ?? 0;
}

public decimal GetPayrunDeductionsAndSupersYTDValue(Guid employeeId, Guid payrunId, Guid payItemId, DateTime paymentDate)
{
   var payrunPayItem = _secondRepository.FilterBy(x => x.EmployeeId == employeeId
                                                  && x.PayrunsId != payrunId
                                                  && x.PayItemId == payItemId
                                                  && x.EffectiveDate <= paymentDate, null)
                    .OrderByDescending(x => x.EffectiveDate).FirstOrDefault();
   return payrunPayItem.YTD ?? 0;
}

public decimal GetPayrunCompanyContributionYTDValue(Guid employeeId, Guid payrunId, Guid payItemId, DateTime paymentDate)
{
   var payrunPayItem = _thirdRepository.FilterBy(x => x.EmployeeId == employeeId
                                                 && x.PayrunsId != payrunId
                                                 && x.PayItemId == payItemId
                                                 && x.EffectiveDate <= paymentDate, null)
                         .OrderByDescending(x => x.EffectiveDate).FirstOrDefault();
   return payrunPayItem.YTD ?? 0;
}

正如您所看到的,这三个函数完全相同,只有一个区别,它们是查询不同的存储库。我试图将其重构为一些通用函数,如下所示:

public decimal GetYtdValue<T>(T repository, Guid employeeId, Guid payrunId, Guid payItemId)
            where T : IReadonlyRepository<FirstRepositoryType>, IReadonlyRepository<SecondRepositoryType>, IReadonlyRepository<ThirdRepositoryType>
{
   var payrunPayItem = repository.FilterBy(x => x.EmployeeId == employeeId
                                                && x.PayrunsId != payrunId
                                    && x.PayItemId == payItemId, null).OrderByDescending(x => x.EffectiveDate).FirstOrDefault();
            return (payrunPayItem.YTD ?? 0);
        }

这里的问题是我收到错误,因为有一个&#34;不明确的引用&#34;因为所有存储库都具有与这些属性相同的基类。

那么,有一种方法可以重构这个并且有一个更优雅但不重复的代码吗?

提前致谢

1 个答案:

答案 0 :(得分:2)

  

这里的问题是我收到错误,因为存在“不明确的引用”,因为所有存储库都具有与这些属性相同的基类。

然后只使用基类作为参数。

function aaa () {
    var args = Array.prototype.slice.call(arguments);
    bbb.apply(undefined, args)
}

function bbb () {
    console.dir(arguments)
}

aaa(1,2,3,4) // calls bbb and bbb's arguments are 1, 2, 3, 4

由于Linq表达式与存储库不同,因此存储库有一些共同点。在这种情况下,它是一个共享的基类。如果他们没有共享基类,你可以将这种共性表达为他们都实现的接口。

<强>更新

  

我不能这样做,因为最后一个属性在每个单独的存储库类中(在最后一行,payrunPayItem.YTD)

然后定义一个包含YTD的接口public decimal GetYtdValue(MyRepoBaseClass repository, Guid employeeId, Guid payrunId, Guid payItemId) ,让每个具体的存储库实现该接口。

IRepository