我有一些情况,我有选择的组合,需要根据选择的内容过滤数据(在这种情况下使用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();
答案 0 :(得分:3)
是的,您可以安装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);
如果您使用AND加入多个条件(而不是像此处那样的OR),则不需要谓词构建器,只需链Where
调用:
if (someCondition)
query = query.Where(x => x.SomeField == someValue);
if (anotherCondition)
query = query.Where(x => x.SomeAnotherField == someAnotherValue);
答案 1 :(得分:1)
在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查询会很尴尬和低效,但这是这个框架生成的大部分代码,所以没什么大不了的。