如何在 Linq EF Core 中进行有条件排序?

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

如何有条件地编写OrderBy? 正如您在 if 和 else 条件中看到的那样,整个 linq 是相同的,只有 orderBy 不同。 在第一种情况下,我按升序排序,在第二种情况下,我按降序排序 如何结合这两个条件以避免代码冗余?

我还想从数据库中获取过滤后的数据,所以我不想将查询存储在变量中并稍后应用 orderBy。

public IAsyncEnumerable<Dictionary> GetDictionaryData(int page,float limit,string? sort,string? name)
{  
    Func<EDMDbContextSQLServer, IAsyncEnumerable<Dictionary>>? query;      
    if(sort=="dictionary_name" || sort=="destination_dataset_name")
    {
        query = EF.CompileAsyncQuery((EDMDbContextSQLServer _dbContext)
                => _dbContext.DictionaryMasterUpdateInfo
                    .Include(dm => dm.DictionaryMaster)
                        .ThenInclude(dm => dm==null ? null : dm.SourceDataSetMaster)
                    .Include(dm => dm.DictionaryMaster)
                        .ThenInclude(dm => dm==null ? null : dm.DestinationDataSetMaster)
                    .AsNoTracking()
                    .Select(x => new Dictionary
                    {
                        DictionaryId = x.DictionaryId,
                        DictionaryName = x.DictionaryMaster!.DictionaryName,
                        DestinationDatasetId = x.DictionaryMaster.DestinationDatasetId,
                        SourceDatasetId = x.DictionaryMaster.SourceDatasetId,
                        IsStandard = x.DictionaryMaster.IsStandard,
                        SourceDataSetName = x.DictionaryMaster.SourceDataSetMaster != null ? x.DictionaryMaster.SourceDataSetMaster.DataSetName : "",
                        DestinationDataSetName = x.DictionaryMaster.DestinationDataSetMaster == null ? "" : x.DictionaryMaster.DestinationDataSetMaster.DataSetName,
                    })
                    .OrderBy(x=>sort=="dictionary_name" ? x.DictionaryName : x.DestinationDataSetName)
                    .Skip((page - 1) * (int)limit)
                    .Take((int)limit));
    }
    else
    {              
        query = EF.CompileAsyncQuery((EDMDbContextSQLServer _dbContext)
                =>_dbContext.DictionaryMasterUpdateInfo
                    .Include(dm => dm.DictionaryMaster)
                        .ThenInclude(dm => dm==null ? null : dm.SourceDataSetMaster)
                    .Include(dm => dm.DictionaryMaster)
                        .ThenInclude(dm => dm==null ? null : dm.DestinationDataSetMaster)
                    .AsNoTracking()
                    .Select(x => new Dictionary
                    {
                        DictionaryId = x.DictionaryId,
                        DictionaryName = x.DictionaryMaster!.DictionaryName,
                        DestinationDatasetId = x.DictionaryMaster.DestinationDatasetId,
                        SourceDatasetId = x.DictionaryMaster.SourceDatasetId,
                        IsStandard = x.DictionaryMaster.IsStandard,
                        SourceDataSetName = x.DictionaryMaster.SourceDataSetMaster != null ? x.DictionaryMaster.SourceDataSetMaster.DataSetName : "",
                        DestinationDataSetName = x.DictionaryMaster.DestinationDataSetMaster == null ? "" : x.DictionaryMaster.DestinationDataSetMaster.DataSetName,
                    })
                    .OrderByDescending(dm => dm.ModifiedOn!.Value.Date)
                    .ThenByDescending(dm => dm.ModifiedOn!.Value.TimeOfDay)
                    .ThenBy(x=>x.DictionaryName)
                    .Skip((page - 1) * (int)limit)
                    .Take((int)limit));
        


    }
    return query(_dbContext);
}
.net linq .net-core entity-framework-core
2个回答
1
投票

这里不需要编译查询,一切都可以简化。

  1. IQueryable
    在调用枚举运算符之前不要执行查询
  2. 如果您有
  3. Include()
    ,则 
    Select
  4. 将被忽略 如果您通过
  5. AsNoTracking()
     生成自定义实体,则不需要 
    Select
  6. 您不必检查空导航属性,EF Core 将处理此问题。
  7. 最好返回
    IQueryable
    ,然后就可以申请
    CountAsync
    ToArrayAsync
    ToListAsync
    等。
public IQueryable<Dictionary> GetDictionaryData(int page, float limit, string? sort, string? name)
{  
    var query = _dbContext.DictionaryMasterUpdateInfo
        .Select(x => new Dictionary
        {
            DictionaryId = x.DictionaryId,
            DictionaryName = x.DictionaryMaster!.DictionaryName,
            DestinationDatasetId = x.DictionaryMaster.DestinationDatasetId,
            SourceDatasetId = x.DictionaryMaster.SourceDatasetId,
            IsStandard = x.DictionaryMaster.IsStandard,
            SourceDataSetName = x.DictionaryMaster.SourceDataSetMaster.DataSetName ?? "",
            DestinationDataSetName = x.DictionaryMaster.DestinationDataSetMaster.DataSetName ?? "",
        });

    switch (sort)
    {
        case "dictionary_name" : query = query.OrderBy(x => x.DictionaryName); break;
        case "destination_dataset_name" : query = query.OrderBy(x => x.DestinationDataSetName); break;
        default : query = query.OrderBy(x => x.DictionaryName)
                     .ThenByDescending(dm => dm.ModifiedOn!.Value.TimeOfDay); 
           break;
    }

    query = query
        .Skip((page - 1) * (int)limit)
        .Take((int)limit);

    return query;
}

0
投票

你可以这样做:

something = EF.CompileAsyncQuery((EDMDbContextSQLServer _dbContext)
                =>_dbContext.DictionaryMasterUpdateInfo
                    .Include(dm => dm.DictionaryMaster)
                        .ThenInclude(dm => dm==null ? null : dm.SourceDataSetMaster)
                    .Include(dm => dm.DictionaryMaster)
                        .ThenInclude(dm => dm==null ? null : dm.DestinationDataSetMaster)
                    .AsNoTracking()
                    .Select(x => new Dictionary
                    {
                        DictionaryId = x.DictionaryId,
                        DictionaryName = x.DictionaryMaster!.DictionaryName,
                        DestinationDatasetId = x.DictionaryMaster.DestinationDatasetId,
                        SourceDatasetId = x.DictionaryMaster.SourceDatasetId,
                        IsStandard = x.DictionaryMaster.IsStandard,
                        SourceDataSetName = x.DictionaryMaster.SourceDataSetMaster != null ? x.DictionaryMaster.SourceDataSetMaster.DataSetName : "",
                        DestinationDataSetName = x.DictionaryMaster.DestinationDataSetMaster == null ? "" : x.DictionaryMaster.DestinationDataSetMaster.DataSetName,
                    });
query = (sort=="dictionary_name" || sort=="destination_dataset_name") ?
(something..OrderBy(x=>sort=="dictionary_name" ? x.DictionaryName : x.DestinationDataSetName)
                    .Skip((page - 1) * (int)limit)
                    .Take((int)limit))) :
(something..OrderByDescending(dm => dm.ModifiedOn!.Value.Date)
                    .ThenByDescending(dm => dm.ModifiedOn!.Value.TimeOfDay)
                    .ThenBy(x=>x.DictionaryName)
                    .Skip((page - 1) * (int)limit)
                    .Take((int)limit)));
© www.soinside.com 2019 - 2024. All rights reserved.