多个过滤选项的查询结构和语法
Query structure and syntax for multiple filtering options
我有一个非常大的数据集。为了优化查询性能,我根据用户选择的过滤器进行查询。
using (_db)
{
if (string.IsNullOrEmpty(CompanyID))
{
if (string.IsNullOrEmpty(HealthplanCode))
{
foreach (string x in _db.BM_OPT_MASTER.Select(y => y.OPT).Distinct())
{
currentComboBox.Items.Add(x);
}
}
else
{
foreach (string x in _db.BM_OPT_MASTER.Where(y => y.HPCODE == HealthplanCode).Select(y => y.OPT).Distinct())
{
currentComboBox.Items.Add(x);
}
}
}
else
{
if (string.IsNullOrEmpty(HealthplanCode))
{
foreach (string x in _db.BM_OPT_MASTER.Where(y => y.COMPANY_ID == CompanyID).Select(y => y.OPT).Distinct())
{
currentComboBox.Items.Add(x);
}
}
else
{
foreach (string x in _db.BM_OPT_MASTER.Where(y => y.COMPANY_ID == CompanyID && y.HPCODE == HealthplanCode).Select(y => y.OPT).Distinct())
{
currentComboBox.Items.Add(x);
}
}
}
}
如您所见,随着越来越多的过滤器选项被添加,这会变得非常烦人。有没有一种方法可以重构此代码,使查询在不依赖嵌套 if else 语句的情况下仍然得到优化?
您可以定义一个带有 "query options" 的自定义 class,您可以填写任何您想要的参数。它看起来像这样:
public class QueryFilterOptions
{
public string CompanyID { get; set; }
public string HealthplanCode { get; set; }
public string SomeOtherQueryOption { get; set; }
}
然后可以这样使用(我不确定你在 BM_OPT_MASTER
中的项目是什么类型,所以我只是接受了):
public void AddItems(QueryFilterOptions options = null) {
using (_db)
{
if (options == null) {
options = new QueryFilterOptions();
}
var items = _db.BM_OPT_MASTER;
items = FilterOnCompanyID(items, options.CompanyID);
items = FilterOnHealthPlanCode(items, options.HealthplanCode);
items = FilterOnSomeOtherQueryOption(items, options.SomeOtherQueryOption);
//...other filters
items = items.Select(y => y.OPT).Distinct();
foreach (var item in items)
{
currentComboBox.Items.Add(item);
}
}
}
private IQueryable<BM_OPT_MASTER> FilterOnCompanyID(IQueryable<BM_OPT_MASTER> items, string companyID)
{
if (!(string.IsNullOrEmpty(companyID)))
{
items = items.Where(y => y.COMPANY_ID == companyID);
}
return items;
}
private IQueryable<BM_OPT_MASTER> FilterOnHealthPlanCode(IQueryable<BM_OPT_MASTER> items, string healthplanCode)
{
if (!(string.IsNullOrEmpty(healthplanCode)))
{
items = items.Where(y => y.HPCODE == healthplanCode);
}
return items;
}
private IQueryable<BM_OPT_MASTER> FilterOnSomeOtherQueryOption(IQueryable<BM_OPT_MASTER> items, string someOtherQueryOption)
{
if (!(string.IsNullOrEmpty(someOtherQueryOption)))
{
items = items.Where(y => y.SOME_OTHER_QUERY_OPTION == someOtherQueryOption);
}
return items;
}
您只需使用您拥有的任何过滤器值调用 AddItems
函数,例如:
AddItems(new QueryFilterOptions
{
CompanyID = "SOME-COMPANY-ID"
});
或
AddItems(new QueryFilterOptions
{
HealthplanCode = "SOME-HEALTHPLAN-CODE",
SomeOtherQueryOption = "SOME-OTHER-QUERY-OPTION"
});
要添加新的查询过滤器选项,只需将新字段添加到 QueryFilterOptions
class 并添加 FilterOn...
方法。
我有一个非常大的数据集。为了优化查询性能,我根据用户选择的过滤器进行查询。
using (_db)
{
if (string.IsNullOrEmpty(CompanyID))
{
if (string.IsNullOrEmpty(HealthplanCode))
{
foreach (string x in _db.BM_OPT_MASTER.Select(y => y.OPT).Distinct())
{
currentComboBox.Items.Add(x);
}
}
else
{
foreach (string x in _db.BM_OPT_MASTER.Where(y => y.HPCODE == HealthplanCode).Select(y => y.OPT).Distinct())
{
currentComboBox.Items.Add(x);
}
}
}
else
{
if (string.IsNullOrEmpty(HealthplanCode))
{
foreach (string x in _db.BM_OPT_MASTER.Where(y => y.COMPANY_ID == CompanyID).Select(y => y.OPT).Distinct())
{
currentComboBox.Items.Add(x);
}
}
else
{
foreach (string x in _db.BM_OPT_MASTER.Where(y => y.COMPANY_ID == CompanyID && y.HPCODE == HealthplanCode).Select(y => y.OPT).Distinct())
{
currentComboBox.Items.Add(x);
}
}
}
}
如您所见,随着越来越多的过滤器选项被添加,这会变得非常烦人。有没有一种方法可以重构此代码,使查询在不依赖嵌套 if else 语句的情况下仍然得到优化?
您可以定义一个带有 "query options" 的自定义 class,您可以填写任何您想要的参数。它看起来像这样:
public class QueryFilterOptions
{
public string CompanyID { get; set; }
public string HealthplanCode { get; set; }
public string SomeOtherQueryOption { get; set; }
}
然后可以这样使用(我不确定你在 BM_OPT_MASTER
中的项目是什么类型,所以我只是接受了):
public void AddItems(QueryFilterOptions options = null) {
using (_db)
{
if (options == null) {
options = new QueryFilterOptions();
}
var items = _db.BM_OPT_MASTER;
items = FilterOnCompanyID(items, options.CompanyID);
items = FilterOnHealthPlanCode(items, options.HealthplanCode);
items = FilterOnSomeOtherQueryOption(items, options.SomeOtherQueryOption);
//...other filters
items = items.Select(y => y.OPT).Distinct();
foreach (var item in items)
{
currentComboBox.Items.Add(item);
}
}
}
private IQueryable<BM_OPT_MASTER> FilterOnCompanyID(IQueryable<BM_OPT_MASTER> items, string companyID)
{
if (!(string.IsNullOrEmpty(companyID)))
{
items = items.Where(y => y.COMPANY_ID == companyID);
}
return items;
}
private IQueryable<BM_OPT_MASTER> FilterOnHealthPlanCode(IQueryable<BM_OPT_MASTER> items, string healthplanCode)
{
if (!(string.IsNullOrEmpty(healthplanCode)))
{
items = items.Where(y => y.HPCODE == healthplanCode);
}
return items;
}
private IQueryable<BM_OPT_MASTER> FilterOnSomeOtherQueryOption(IQueryable<BM_OPT_MASTER> items, string someOtherQueryOption)
{
if (!(string.IsNullOrEmpty(someOtherQueryOption)))
{
items = items.Where(y => y.SOME_OTHER_QUERY_OPTION == someOtherQueryOption);
}
return items;
}
您只需使用您拥有的任何过滤器值调用 AddItems
函数,例如:
AddItems(new QueryFilterOptions
{
CompanyID = "SOME-COMPANY-ID"
});
或
AddItems(new QueryFilterOptions
{
HealthplanCode = "SOME-HEALTHPLAN-CODE",
SomeOtherQueryOption = "SOME-OTHER-QUERY-OPTION"
});
要添加新的查询过滤器选项,只需将新字段添加到 QueryFilterOptions
class 并添加 FilterOn...
方法。