linq查询中的条件条件

问题描述 投票:0回答:1

我想从linq查询中返回总和,我传入了2个可能/可能不包含在查询中的参数。

OrgId-int

reportType-in​​t

所以有两个问题:

  1. 我如何更新下面的查询,以便如果OrgId = 0则忽略组织字段(全部返回)?

  2. LocumClaimTF可以为True / False / Both,如果两者都忽略,则忽略此字段的where查询。

[到目前为止,我已经做过了,现在可以正常运行,但是我想提高效率。

            // Using reportType set preferences for LocumClaimTF
            bool locumClaimTF1, locumClaimTF2 = false;
            if (reportType == 0)
            {
                locumClaimTF1 = false;
                locumClaimTF2 = false;
            }
            else if (reportType == 1)
            {
                locumClaimTF1 = true;
                locumClaimTF2 = true;
            }
            else // 2
            {
                locumClaimTF1 = true;
                locumClaimTF2 = false;
            }

            if (OrgID != 0) // Get by OrgID
            {
                return _UoW.ShiftDates.Get(x => x.shiftStartDate >= StartDate && x.shiftEndDate <= EndDate)
             .Where(x => x.Shift.LocumClaimTF == locumClaimTF1 || x.Shift.LocumClaimTF == locumClaimTF2)
             .Where(x => x.Shift.organisationID == OrgID)
             .GroupBy(s => s.assignedLocumID)
                 .Select(g => new dataRowDTO { dataLabel = string.Concat(g.FirstOrDefault().User.FullName), dataCount = g.Count(), dataCurrencyAmount = g.Sum(sd => sd.shiftDateTotal.Value) }
                ).Sum(g=>g.dataCurrencyAmount);
            }
            else // Ignore OrgID - Get ALL Orgs
            {
                return _UoW.ShiftDates.Get(x => x.shiftStartDate >= StartDate && x.shiftEndDate <= EndDate)
               .Where(x => x.Shift.LocumClaimTF == locumClaimTF1 || x.Shift.LocumClaimTF == locumClaimTF2)
               .GroupBy(s => s.assignedLocumID)
                  .Select(g => new dataRowDTO { dataLabel = string.Concat(g.FirstOrDefault().User.FullName), dataCount = g.Count(), dataCurrencyAmount = g.Sum(sd => sd.shiftDateTotal.Value) }
                  ).Sum(g => g.dataCurrencyAmount);
            }

我正在使用带有工作单元模式的EF来获取数据frm

entity-framework linq linq-to-entities
1个回答
0
投票

几件事,从上到下:

用于处理布尔值

bool locumClaimTF1 = (reportType == 1 || reportType == 2);
bool locumClaimTF2 = (reportType == 1);

不过,根据我在查询中看到的内容,如果报告类型为1或2,则您希望Shift的LocumClaimTF标志必须为True。如果是这种情况,那么您可以忘记布尔标志,而仅在您的条件下使用reportType。

接下来,要组成查询,您可以有条件地组成where子句。关于流畅的Linq语法,这是一件好事。但是,让我们暂时从常规DbContext而不是UoW开始,因为这会带来一些复杂性和您需要研究的问题。 (我将在下面介绍)

using (var context = new ApplicationDbContext()) // <- insert your DbContext here...
{
    var query = context.ShiftDates
       .Where(x => x.shiftStartDate >= StartDate 
           && x.shiftEndDate <= EndDate);
    if (reportType == 1 || reportType == 2)
       query = query.Where(x.Shift.LocumClaimTF);
    if (OrgId > 0)
       query = query.Where(x => x.Shift.organisationID == OrgID);

    var total = query.GroupBy(s => s.assignedLocumID)
        .Select(g => new dataRowDTO 
        { 
           dataLabel = tring.Concat(g.FirstOrDefault().User.FullName), 
           dataCount = g.Count(), 
           dataCurrencyAmount = g.Sum(sd => sd.shiftDateTotal.Value) 
        })
        .Sum(g=>g.dataCurrencyAmount);
}

现在,这里没有任何意义。您为什么要对数据进行分组,计数和求和,而只是为了求和?我怀疑您已复制了一个现有查询,该查询正在为分组结果选择DTO。如果不需要分组结果,则只需要总计。因此,在这种情况下,请取消分组,仅取所有适用记录的总和:

    var total = query.Sum(x => x.shiftDateTotal.Value);

所以整个过程看起来像:

using (var context = new ApplicationDbContext()) // <- insert your DbContext here...
{
    var query = context.ShiftDates
       .Where(x => x.shiftStartDate >= StartDate 
           && x.shiftEndDate <= EndDate);
    if (reportType == 1 || reportType == 2)
       query = query.Where(x.Shift.LocumClaimTF);
    if (OrgId > 0)
       query = query.Where(x => x.Shift.organisationID == OrgID);

    var total = query.Sum(x => x.shiftDateTotal.Value);
    return total;
}

返回工作单元:使用此模式时,主要考虑因素是确保此Get调用绝对必须返回一个IQueryable<TEntity>。如果它返回其他任何内容,例如IEnumerable<TEntity>,那么您将面临严重的性能问题,因为它将返回已加载到内存中的实体的物化列表,而不是您可以扩展以建立对数据库的有效查询的东西。如果Get方法没有返回IQueryable,或其中的任何位置都包含ToList之类的方法,然后再包含AsQueryable(),那么请与开发团队的其他成员进行讨论,因为您实际上就是站在代码上/ EF相当于地雷。如果确实返回IQueryable<TEntity>(在这种情况下为IQueryable<ShiftDate>),则可以将其代入上述查询:

var query = _UoW.ShiftDates.Get(x => x.shiftStartDate >= StartDate && x.shiftEndDate <= EndDate);
if (reportType == 1 || reportType == 2)
   query = query.Where(x.Shift.LocumClaimTF);
if (OrgId > 0)
   query = query.Where(x => x.Shift.organisationID == OrgID);

var total = query.Sum(x => x.shiftDateTotal.Value);
return total;
© www.soinside.com 2019 - 2024. All rights reserved.