使用多个where子句的Entity Framework Core LINQ查询

9

我需要一些适用于我的项目的样例代码。我正在使用EF CORE 2.1.1。

我创建了一个函数,它接受3个参数,在该函数内我执行了一个LINQ( lambda表达式查询),然后返回一个列表。

这是我的函数:

public IEnumerable<Donneesource> GetAllSourcesFromBDD(DateTime PremierDateCom, DateTime DerniereDateCom, string Secteur)
{
    try
    {
        //Récupération des données.
             IEnumerable<Donneesource> RawDatas = _sourceDAL.Donneesource
                .Where(ic => ic.EstCopieDestination == false)
                .Where(s => PremierDateCom != DateTime.MinValue && s.SComPremierDate.Value.Date == PremierDateCom.Date)
                .Where(s => DerniereDateCom != DateTime.MinValue && s.SComDerniereDate.Value.Date == DerniereDateCom.Date)                    
                .Where(s => Secteur != string.Empty && s.SSectNom == Secteur)
                .ToList();

        return RawDatas;              
    }
    catch(Exception)
    { 
        return null;
    }
}

默认情况下,我将DateTime参数设置为DateTime.MinValue(PremierDateCom,DerniereDateCom),将字符串参数设置为string.Empty(Secteur)。
我正在尝试创建一个带有where子句的单个查询。如果使用默认参数,则希望忽略where子句。例如,如果PremierDateCom = DateTime.MinValue(或其他参数),则希望在查询中忽略where子句,如果需要包含where子句,则应该在查询中添加。
我不想创建这样的查询:
  //Filtre
            if (PremierDateCom != DateTime.MinValue)
                RawDatas = RawDatas.Where(x => x.SComPremierDate.Value.ToShortDateString() == PremierDateCom.ToShortDateString());
            //Filtre
            if (DerniereDateCom != DateTime.MinValue)
                RawDatas = RawDatas.Where(x => x.SComDerniereDate.Value.ToShortDateString() == DerniereDateCom.ToShortDateString());   
            //Filtre                
            if (Secteur != null)
                RawDatas = RawDatas.Where(x => x.SSectNom == Secteur);

1
为什么你不想创建像最后一段代码块那样的查询呢?那是最有效的方法。 - DavidG
性能问题,我不想从SQLServer中检索所有数据,然后进行过滤,在我的情况下,我的表中有超过10万行。 - d_raja_23
3
那么你需要了解 IQueryable 以及它的工作原理。假设 _sourceDAL.Donneesource 返回一个 IQueryable,那么它不会效率低下。 - DavidG
但如何使用IQueryable创建3个where参数? .Where(ic => ic.EstCopieDestination == false) .Where(s => PremierDateCom != DateTime.MinValue && s.SComPremierDate.Value.Date == PremierDateCom.Date) .Where(s => DerniereDateCom != DateTime.MinValue && s.SComDerniereDate.Value.Date == DerniereDateCom.Date)。如果带有默认值的参数只想忽略那些子句。 - d_raja_23
2个回答

18
假设 _sourceDAL.Donneesource 给你一个 IQueryable<T>,那么你应该在 if 语句内部添加 Where 子句构建查询。这是因为 IQueryable 不会立即对数据库运行查询,直到它被实例化,例如使用 foreach 或者 .ToList()。所以代码应该像这样:
IQueryable<Donneesource> RawDatas = _sourceDAL.Donneesource
    .Where(ic => ic.EstCopieDestination == false)
    .Where(s => PremierDateCom != DateTime.MinValue && s.SComPremierDate.Value.Date == PremierDateCom.Date)
    .Where(s => DerniereDateCom != DateTime.MinValue && s.SComDerniereDate.Value.Date == DerniereDateCom.Date)                    
    .Where(s => Secteur != string.Empty && s.SSectNom == Secteur);

if (PremierDateCom != DateTime.MinValue)
{
    RawDatas = RawDatas.Where(x => x.SComPremierDate.Value.ToShortDateString() == PremierDateCom.ToShortDateString());
}

if (DerniereDateCom != DateTime.MinValue)
{
    RawDatas = RawDatas.Where(x => x.SComDerniereDate.Value.ToShortDateString() == DerniereDateCom.ToShortDateString());   
}

if (Secteur != null)
{
    RawDatas = RawDatas.Where(x => x.SSectNom == Secteur);
}

//Now get the data from the database:

return RawDatas.ToList();

4
为避免使用过多的if语句,您也可以尝试以下方法:
IQueryable<Donneesource> RawDatas = _sourceDAL.Donneesource
.Where(ic => !ic.EstCopieDestination)
.Where(s => PremierDateCom != DateTime.MinValue ? s.SComPremierDate.Value.Date == PremierDateCom.Date : true)
.Where(s => DerniereDateCom != DateTime.MinValue ? s.SComDerniereDate.Value.Date == DerniereDateCom.Date : true)
.Where(s => Secteur != string.Empty ? s.SSectNom == Secteur : true);

您可以使用条件语句,如果条件未满足,则传递true


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接