C# 用于链接查询组合的Linq语法

C# 用于链接查询组合的Linq语法,c#,linq,C#,Linq,我有一些情况下,我有选择的组合,需要根据选择的内容过滤数据(在本例中使用EF)。是否有更简洁的方法来编写以下内容,而不是列出所有的组合 我在下面的最初尝试似乎过于复杂,尤其是当组合变得更大时 DateTime today = DateTime.Now.Date; DateTime yesterday = today.AddDays(-1); DateTime tomorrow = today.AddDays(1); var query = db.Products.AsQueryable();

我有一些情况下,我有选择的组合,需要根据选择的内容过滤数据(在本例中使用EF)。是否有更简洁的方法来编写以下内容,而不是列出所有的组合

我在下面的最初尝试似乎过于复杂,尤其是当组合变得更大时

DateTime today = DateTime.Now.Date;
DateTime yesterday = today.AddDays(-1);
DateTime tomorrow = today.AddDays(1);

var query = db.Products.AsQueryable();
if (userSettings.DisplayYesterday && userSettings.DisplayToday && userSettings.DisplayTomorrow)
{
    query = query.Where(x => DbFunctions.TruncateTime(x.ListedTime) == yesterday || DbFunctions.TruncateTime(x.ListedTime) == today || DbFunctions.TruncateTime(x.ListedTime) == tomorrow);
}
else if (!userSettings.DisplayYesterday && userSettings.DisplayToday && userSettings.DisplayTomorrow)
{
    query = query.Where(x => DbFunctions.TruncateTime(x.ListedTime) == today || DbFunctions.TruncateTime(x.ListedTime) == tomorrow);
}
else if (userSettings.DisplayYesterday && !userSettings.DisplayToday && userSettings.DisplayTomorrow)
{
    query = query.Where(x => DbFunctions.TruncateTime(x.ListedTime) == yesterday || DbFunctions.TruncateTime(x.ListedTime) == tomorrow);
}
else if (userSettings.DisplayYesterday && userSettings.DisplayToday && !userSettings.DisplayTomorrow)
{
    query = query.Where(x => DbFunctions.TruncateTime(x.ListedTime) == yesterday || DbFunctions.TruncateTime(x.ListedTime) == today);
}
else if (!userSettings.DisplayYesterday && !userSettings.DisplayToday && userSettings.DisplayTomorrow)
{
    query = query.Where(x => DbFunctions.TruncateTime(x.ListedTime) == tomorrow);
}
else if (!userSettings.DisplayYesterday && userSettings.DisplayToday && !userSettings.DisplayTomorrow)
{
    query = query.Where(x => DbFunctions.TruncateTime(x.ListedTime) == today);
}
else if (userSettings.DisplayYesterday && !userSettings.DisplayToday && !userSettings.DisplayTomorrow)
{
    query = query.Where(x => DbFunctions.TruncateTime(x.ListedTime) == yesterday);
}
else if (userSettings.DisplayYesterday && !userSettings.DisplayToday && !userSettings.DisplayTomorrow)
{
    query = query.Where(x => DbFunctions.TruncateTime(x.ListedTime) == yesterday);
}
else if (!userSettings.DisplayYesterday && !userSettings.DisplayToday && !userSettings.DisplayTomorrow)
{
    //  If nothing is selected then default to today
    query = query.Where(x => DbFunctions.TruncateTime(x.ListedTime) == today);
}

List<Products> productList = await query.ToListAsync();
DateTime today=DateTime.Now.Date;
DateTime昨天=今天.AddDays(-1);
DateTime明天=今天。AddDays(1);
var query=db.Products.AsQueryable();
if(userSettings.displaytheday&&userSettings.displaytouday&&userSettings.displaytounday)
{
query=query.Where(x=>DbFunctions.TruncateTime(x.ListedTime)==昨天| | | DbFunctions.TruncateTime(x.ListedTime)==今天| | DbFunctions.TruncateTime(x.ListedTime)==明天);
}
如果(!userSettings.displaydevery&&userSettings.displaydounday&&userSettings.displaydounday),则为else
{
query=query.Where(x=>DbFunctions.TruncateTime(x.ListedTime)==今天| | DbFunctions.TruncateTime(x.ListedTime)==明天);
}
else if(userSettings.displayDayed&&!userSettings.DisplayToday&&userSettings.display明天)
{
query=query.Where(x=>DbFunctions.TruncateTime(x.ListedTime)==昨天| | DbFunctions.TruncateTime(x.ListedTime)==明天);
}
else if(userSettings.displayDayed&&userSettings.DisplayToday&&!userSettings.DisplayToday)
{
query=query.Where(x=>DbFunctions.TruncateTime(x.ListedTime)==昨天| | DbFunctions.TruncateTime(x.ListedTime)==今天);
}
如果(!userSettings.displaytheday&&!userSettings.displaytouday&&userSettings.displaytounday),则为else
{
query=query.Where(x=>DbFunctions.TruncateTime(x.ListedTime)==明天);
}
如果(!userSettings.displaydevery&&userSettings.displaydounday&&userSettings.displaydounday),则为else
{
query=query.Where(x=>DbFunctions.TruncateTime(x.ListedTime)==today);
}
else if(userSettings.displaytheday&&!userSettings.displaytouday&&!userSettings.displaytounday)
{
query=query.Where(x=>DbFunctions.TruncateTime(x.ListedTime)==昨天);
}
else if(userSettings.displaytheday&&!userSettings.displaytouday&&!userSettings.displaytounday)
{
query=query.Where(x=>DbFunctions.TruncateTime(x.ListedTime)==昨天);
}
如果(!userSettings.displaytheday&&!userSettings.displaytheday&&!userSettings.displaytheday),则为else
{
//如果未选择任何内容,则默认为今天
query=query.Where(x=>DbFunctions.TruncateTime(x.ListedTime)==today);
}
List productList=WAIT query.ToListAsync();

是的,您可以安装LinqKit nuget软件包并使用其
PredicateBuilder
(如果出于任何原因您不能\不想安装第三方软件包,您可以自己实现类似的功能)。使用
PredicateBuilder
可以这样做:

// start with false, because building OR expression
// and false OR something is the same as just something
var condition = PredicateBuilder.New<Product>(false);
if (userSettings.DisplayYesterday)
    condition = condition.Or(x => DbFunctions.TruncateTime(x.ListedTime) == yesterday);
if (userSettings.DisplayToday)
    condition = condition.Or(x => DbFunctions.TruncateTime(x.ListedTime) == today);
if (userSettings.DisplayTomorrow)
    condition = condition.Or(x => DbFunctions.TruncateTime(x.ListedTime) == tomorrow);
query = query.Where(condition);

在Linq2Sql中,您可以编写

bool dispYesterday = userSettings.DisplayYesterday;
bool dispTomorrow = userSettings.DisplayTomorrow;
bool dispToday = userSettings.DisplayToday || !dispYesterday && !dispTomorrow;

query = query.Where(x =>
    dispYesterday && x.ListedTime.Date == yesterday
 || dispToday && x.ListedTime.Date == today
 || dispTomorrow && x.ListedTime.Date == tomorrow
);

它只生成所使用的条件,从而进行有效的查询。在EF中,您可以编写一些类似的东西,生成的sql查询将是笨拙和低效的,但这是该框架生成的大部分代码,所以不是什么大问题。

非常好,这非常干净。谢谢。@pathDongle我已经用一个更好的解决方案(我想)更新了一点答案,来解决这个关于日期的特殊情况。谢谢,我不是特别想找一个日期解决方案,它只是组合。我对日期很有信心,也知道日期时间。在这种情况下,现在是正确的。再次感谢。@AntonínLejsek你说得对,谢谢。我从答案中删除了这一部分。
bool dispYesterday = userSettings.DisplayYesterday;
bool dispTomorrow = userSettings.DisplayTomorrow;
bool dispToday = userSettings.DisplayToday || !dispYesterday && !dispTomorrow;

query = query.Where(x =>
    dispYesterday && x.ListedTime.Date == yesterday
 || dispToday && x.ListedTime.Date == today
 || dispTomorrow && x.ListedTime.Date == tomorrow
);