一、需求
例:现有一数据表存储筛选规则,如下表
| 年龄 | 性别 | 负责人 |
|---|---|---|
| 大于20 | 男 | 张三 |
| 小于20 | 男 | 李四 |
| 大于20 | 女 | 王五 |
根据筛选条件,选择负责人,若后期新增或修改筛选规则,要求不能和之前重复
如添加下面条件,则符合规则
| 年龄 | 性别 | 负责人 |
|---|---|---|
| 小于20 | 女 | 赵六 |
若添加下面条件,则不符合规则,因为与第一条数据的筛选条件冲突
| 年龄 | 性别 | 负责人 |
|---|---|---|
| 大于20 | 男 | 赵六 |
二、逻辑说明
2.1 创建实体类
假设有4个筛选条件,分别抽象为F1,F2,F3,F4
2.2 筛选规则说明
并且可取的值只能为三种:
- 数字(表示该条件对应的id)
- ALL (不进行筛选)
- ELSE (若所有筛选条件没有命中,则选择该条件)
初始化数据:
假设数据库存放三条筛选规则:
第一条:
| F1 | F2 | F3 | F4 | ID |
|---|---|---|---|---|
| 1,2,3,4 | 2,3,4 | ALL | ALL | 1 |
一共有 4 * 3 = 12种条件,此时若符合则让ID为1的用户处理,该12种分别是:
第二条:
| F1 | F2 | F3 | F4 | ID |
|---|---|---|---|---|
| ALL | 2,3,4 | ALL | ALL | 2 |
一共有 3 种条件,此时若符合则让ID为2的用户处理,分别是:
第二条:
| F1 | F2 | F3 | F4 | ID |
|---|---|---|---|---|
| ELSE | ELSE | ELSE | ELSE | 3 |
若上述条件都没有命中,则让ID为3的用户处理
2.3 新增筛选条件
2.3.1 在 新增的数据与数据库中内容重复 的条件下
如新增一条筛选规则,让id为4的用户处理
此时数据重复,将会报错并返回重复信息,以下是重复信息
2.3.2 在 新增的数据与数据库中内容不重复 的条件下
如新增一条不重复的筛选规则,让id为4的用户处理
此时由于没有重复信息,将不会返回重复列表
2.4 修改筛选条件
分别定义before和after,分别代表要修改的数据,和要修改后的数据
要求修改后的规则,不能与现有规则冲突
2.4.1 在 修改后的数据与已有内容重复 的条件下
例如修改后的条件与第一行内容重复,要求返回重复的条件列表
2.4.2 在 修改后的数据与已有内容不重复 的条件下
当修改后后的条件不与现有的冲突时,则可正常修改
三、代码实现
3.1 实体类
public class Filter
{
public int Id { get; set; }
public string F1 { get; set; }
public string F2 { get; set; }
public string F3 { get; set; }
public string F4 { get; set; }
}
3.2 返回结果类
public class ResultHandler
{
public bool flag { get; set; }
public List<Filter> filters { get; set; }
public ResultHandler()
{
flag = false;
filters = new List<Filter>();
}
}
3.2 处理过程
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace select
{
internal static class Helper
{
public static ResultHandler IsExist(Filter before, Filter after,List<Filter> list)
{
// 分别拆解
List<string> b1 = GetListByString(before.F1);
List<string> b2 = GetListByString(before.F2);
List<string> b3 = GetListByString(before.F3);
List<string> b4 = GetListByString(before.F4);
List<string> a1 = GetListByString(after.F1);
List<string> a2 = GetListByString(after.F2);
List<string> a3 = GetListByString(after.F3);
List<string> a4 = GetListByString(after.F4);
ResultHandler resultHandler = new ResultHandler();
bool isBefore = false;
int index = 1;
list.ForEach(x =>
{
b1.ForEach(a =>
{
b2.ForEach(b =>
{
b3.ForEach(c =>
{
b4.ForEach(d =>
{
if (x.F1.Equals(a) && x.F2.Equals(b) && x.F3.Equals(c) && x.F4.Equals(d))
{
Console.WriteLine($"遇到自己,跳过:f1:{a},f2:{b},f3:{c},f4:{d}");
isBefore = true;
return; // 直接返回到 f4.ForEach 的下一个元素
}
});
if (isBefore) return; // 跳出 f3.ForEach
});
if (isBefore) return; // 跳出 f2.ForEach
});
if (isBefore) return; // 跳出 f1.ForEach
});
// Console.WriteLine($"现在是第{index ++ }次循环");
if (isBefore) return; // 跳出 list.ForEach
else
{
// Console.WriteLine("不是自己,处理");
bool found = false;
a1.ForEach(a =>
{
a2.ForEach(b =>
{
a3.ForEach(c =>
{
a4.ForEach(d =>
{
if (x.F1.Equals(a) && x.F2.Equals(b) && x.F3.Equals(c) && x.F4.Equals(d))
{
resultHandler.flag = true;
resultHandler.filters.Add(new Filter
{
F1 = a,
F2 = b,
F3 = c,
F4 = d
});
found = true;
return; // 直接返回到 f4.ForEach 的下一个元素
}
});
if (found) return; // 跳出 f3.ForEach
});
if (found) return; // 跳出 f2.ForEach
});
if (found) return; // 跳出 f1.ForEach
});
}
});
return resultHandler;
}
public static ResultHandler IsExist(Filter target,List<Filter> list)
{
// 拆解target
List<string> f1 = GetListByString(target.F1);
List<string> f2 = GetListByString(target.F2);
List<string> f3 = GetListByString(target.F3);
List<string> f4 = GetListByString(target.F4);
ResultHandler resultHandler = new ResultHandler();
bool found = false;
list.ForEach(x =>
{
f1.ForEach(a =>
{
f2.ForEach(b =>
{
f3.ForEach(c =>
{
f4.ForEach(d =>
{
if (x.F1.Equals(a) && x.F2.Equals(b) && x.F3.Equals(c) && x.F4.Equals(d))
{
resultHandler.flag = true;
resultHandler.filters.Add(new Filter
{
F1 = a,
F2 = b,
F3 = c,
F4 = d
});
found = true;
return; // 直接返回到 f4.ForEach 的下一个元素
}
});
if (found) return; // 跳出 f3.ForEach
});
if (found) return; // 跳出 f2.ForEach
});
if (found) return; // 跳出 f1.ForEach
});
if (found) return; // 跳出 list.ForEach
});
return resultHandler;
}
public static List<Filter> GetFilter(int id,List<string>l1, List<string> l2, List<string> l3, List<string> l4)
{
List<Filter> filters = new List<Filter>();
l1.ForEach(a =>
{
l2.ForEach(b =>
{
l3.ForEach(c =>
{
l4.ForEach(d =>
{
filters.Add(new Filter {
Id = id,
F1 = a,
F2 = b,
F3 = c,
F4 = d
});
});
});
});
});
return filters;
}
public static List<string> GetListByString(string str)
{
if("ALL".Equals(str) || "ELSE".Equals(str))
{
return new List<string> { str };
}
else
{
List<string> list = new List<string>();
string[] strings = str.Split(',');
for(int i = 0; i < strings.Length; i++)
{
list.Add(strings[i]);
}
return list;
}
}
public static List<Filter> Get()
{
Filter f1 = new Filter
{
F1 = "1,2,3,4" ,
F2 = "2,3,4" ,
F3 = "ALL" ,
F4 = "ALL"
};
Filter f2 = new Filter
{
F1 = "ALL",
F2 = "2,3,4",
F3 = "ALL",
F4 = "ALL"
};
Filter f3 = new Filter
{
F1 = "ELSE",
F2 = "ELSE",
F3 = "ELSE",
F4 = "ELSE"
};
return new List<Filter>()
{
f1,f2,f3
};
}
}
}
3.3 逻辑测试
// See https://aka.ms/new-console-template for more information
using select;
List<Filter> data = Helper.Get();
// 生成条件集合
List<Filter> result = new List<Filter>();
int index = 1;
data.ForEach(x =>
{
string f1 = x.F1;
string f2 = x.F2;
string f3 = x.F3;
string f4 = x.F4;
List<string> f1List = Helper.GetListByString(f1);
List<string> f2List = Helper.GetListByString(f2);
List<string> f3List = Helper.GetListByString(f3);
List<string> f4List = Helper.GetListByString(f4);
result.AddRange(Helper.GetFilter(index++, f1List, f2List, f3List, f4List));
});
Console.WriteLine(result);
// add
// 1. 测试重复: 1 2 ALL ALL
Filter filter1 = new Filter
{
Id = 4,
F1 = "1,2,3",
F2 = "2",
F3 = "ALL",
F4 = "ALL",
};
var res = Helper.IsExist(filter1,result);
Console.WriteLine(res);
// 2.测试不重复
Filter filter2 = new Filter
{
Id = 4,
F1 = "6,7,8",
F2 = "2",
F3 = "ALL",
F4 = "ALL",
};
var res2 = Helper.IsExist(filter2, result);
Console.WriteLine(res2);
// update: before => after
Filter before = new Filter
{
Id = 2,
F1 = "ALL",
F2 = "2,3,4",
F3 = "ALL",
F4 = "ALL",
};
// 修改后重复
Filter after = new Filter
{
Id = 2,
F1 = "1,2,3",
F2 = "2",
F3 = "ALL",
F4 = "ALL",
};
var res3 = Helper.IsExist(before, after, result);
Console.WriteLine(res3);
// 修改后不重复
Filter after1 = new Filter
{
Id = 2,
F1 = "6,7,8",
F2 = "2",
F3 = "ALL",
F4 = "ALL",
};
var res4 = Helper.IsExist(before, after1, result);
Console.WriteLine(res4);