2016-08-05 190 views
-1

我有一个类似于下面的方法,即在筛选和排序后获取列表。C#中,如何组织这段代码?

var sample = dbContext.sample; 

// search 
if (!String.IsNullOrEmpty(searchModel.name)){ 
    sample = sample.Where(x=> x.name == searchModel.name); 
} 

if (!String.IsNullOrEmpty(searchModel.modelNo)){ 
    sample = sample.Where(x=> x.modelNo == searchModel.modelNo); 
} 

if (!String.IsNullOrEmpty(searchModel.serialNo)){ 
    sample = sample.Where(x=> x.serialNo == searchModel.serialNo); 
} 

if (!String.IsNullOrEmpty(searchModel.manufacture)){ 
    sample = sample.Where(x=> x.manufacture == searchModel.manufacture); 
} 

if (!String.IsNullOrEmpty(searchModel.managerId)){ 
    sample = sample.Where(x=> x.managerId == searchModel.managerId); 
} 

if (!String.IsNullOrEmpty(searchModel.location)){ 
    sample = sample.Where(x=> x.location == searchModel.location); 
} 

// sort 
if (searchModel.sortMethod == 'asc') { 
    switch (searchModel.sortField) { 
     case 'name': 
      sample = sample.OrderBy(x => x.name); 
      break; 
     case 'modelNo': 
      sample = sample.OrderBy(x => x.modelNo); 
      break; 
     case 'serialNo': 
      sample = sample.OrderBy(x => x.serialNo); 
      break; 
     case 'manufacture': 
      sample = sample.OrderBy(x => x.manufacture); 
      break; 
     case 'managerId': 
      sample = sample.OrderBy(x => x.managerId); 
      break; 
     case 'location': 
      sample = sample.OrderBy(x => x.location); 
      break; 
     default: 
      sample = sample.OrderBy(x => x.id); 
      break; 
    } 
} else { 
    switch (searchModel.sortField) { 
     case 'name': 
      sample = sample.OrderByDescending(x => x.name); 
      break; 
     case 'modelNo': 
      sample = sample.OrderByDescending(x => x.modelNo); 
      break; 
     case 'serialNo': 
      sample = sample.OrderByDescending(x => x.serialNo); 
      break; 
     case 'manufacture': 
      sample = sample.OrderByDescending(x => x.manufacture); 
      break; 
     case 'managerId': 
      sample = sample.OrderByDescending(x => x.managerId); 
      break; 
     case 'location': 
      sample = sample.OrderByDescending(x => x.location); 
      break; 
     default: 
      sample = sample.OrderByDescending(x => x.id); 
      break; 
    } 
} 

return sample.ToList(); 

这是肮脏和很长,所以我用不同的方法,如组织,

private DbSet<Sample> Filter(DbSet<sample> sample, SearchModel searchModel) { 
    // search 
    if (!String.IsNullOrEmpty(searchModel.name)){ 
     sample = sample.Where(x=> x.name == searchModel.name); 
    } 
    //... 
    return sample; 
} 

private DbSet<Sample> Sorting(DbSet<sample> sample, SearchModel searchModel) { 
    // sort 
    if (searchModel.sortMethod == 'asc') { 
     switch (searchModel.sortField) { 
      case 'name': 
       sample = sample.OrderBy(x => x.name); 
       break; 
     return sample; 
    // ... 

    return sample; 
} 

现在是一个小组织,但仍然是很长的。

我不认为Pro将永远不会做这种方式。

请咨询我,我怎么能很好地清洁该组织的代码。

+6

我认为这个问题是比较适合[代码审查(http://codereview.stackexchange.com/) – gudthing

+0

你是否会让问题更具体,例如“重构如果杂牌”或“重构开关” – mrAtari

回答

2

幸运的是,你可以通过使用反射

sample = sample.OrderBy(x=> x.GetType().GetProperty(searchModel.sortField).GetValue(x, null)); 

sample = sample.OrderByDescending(x=> x.GetType().GetProperty(searchModel.sortField).GetValue(x, null)); 
+1

这是从视图代码点的数量更好的方法,但是我不建议在任何生产代码 – meJustAndrew

+0

使用反射@meJustAndrew我完全同意。 – Sherlock

+0

@meJustAndrew哦,我的天啊,我用反射,你能解释为什么不推荐使用反射吗? –

2

为什么不使用Dictionary<SearchModel, Action>。 谷歌的“重构开关语句”。

希望这个示例展示了这个想法:

var actions = new Dictionary<SearchModel, Func<string, bool>>{ 
      {SearchModel.name, x=> x == SearchModel.name.ToString()}, 
      {SearchModel.serialNumber, x=> x == SearchModel.serialNumber.ToString()} 
}; 

var searchKey = SearchModel.name; //get it programmatically 
sample.Where(actions[searchKey]); //run action from dictionary 

这可以肯定做了很多更优雅。

第二种方法是“替换条件与多态性”。

+0

添加为评论 – Sherlock

+2

如果扩大这个它可能成为一个好答案 – MickyD

0

这是我想出了实现这一目标。这绝不是最短的,但我认为可读性很好。首先,写一个扩展方法来筛选样品(需要把它在一个静态类):

public static DbSet<Sample> Filter(
    this DbSet<sample> sample, 
    string modelProperty, 
    Func<sample, bool> selector) 
{ 
    if (!String.IsNullOrEmpty(modelProperty)) 
    { 
     return sample.Where(selector); 
    } 

    return sample; 
} 

然后整个“搜索”部分变为:

return sample 
    .Filter(searchModel.name, x => x.name) 
    .Filter(searchModel.modelNo, x => x.modelNo) 
    .Filter(searchModel.serialNo, x => x.serialNo) 
    .Filter(searchModel.manufacture, x => x.manufacture) 
    .Filter(searchModel.managerId, x => x.managerId) 
    .Filter(searchModel.location, x => x.location) 
    .Filter(searchModel.id, x => x.id); 

排序部分可以简化至: (1)首先按升序排序, (2)如果需要,则将其反转。

switch (searchModel.sortField) { 
    case 'name': 
     sample = sample.OrderBy(x => x.name); 
     break; 
    case 'modelNo': 
     sample = sample.OrderBy(x => x.modelNo); 
     break; 
    case 'serialNo': 
     sample = sample.OrderBy(x => x.serialNo); 
     break; 
    case 'manufacture': 
     sample = sample.OrderBy(x => x.manufacture); 
     break; 
    case 'managerId': 
     sample = sample.OrderBy(x => x.managerId); 
     break; 
    case 'location': 
     sample = sample.OrderBy(x => x.location); 
     break; 
    default: 
     sample = sample.OrderBy(x => x.id); 
     break; 
} 

if (searchModel.sortMethod != 'asc') { 
    sample = sample.Reverse(); 
} 
+0

返回样本。其中(x => x。name == modelProperty); <=这会按名称过滤,不是吗? –

+0

对不起,这是一个愚蠢的错误。修复。 – jetstream96

+0

真棒,非常感谢你! –