如果使用db处理多个OR情况,则简化的最佳方法



我正在做一个项目,在这个项目中,各种文件都要上传到一个平台上。该平台有100多个DocumentTypeIds。这些文件没有设置命名约定。因此,为了确定文件的DoumentTypeId,我目前正在一个返回字符串的方法中执行此操作

if (fileName.Contains("401k") || fileName.Contains("401(k)") || fileName.Contains("457b") || fileName.Contains("457(b)") || fileName.Contains("retire"))
{
return "401k-and-retirement";
}
else if (fileName.Contains("aflac"))
{
return "aflac";
}
else if ( fileName.Contains("beneficiary form") || fileName.Contains("beneficiaries") || fileName.Contains("beneficiary")
)
{
return "beneficiary-forms";
}
else if (fileName.Contains("benefit enrollment") || fileName.Contains("benefits enrollment") || fileName.Contains("benefit form") || fileName.Contains("benefits form") || fileName.Contains("benefit paperwork") || fileName.Contains("qualifying event") || fileName.Contains("enrollment") || fileName.Contains("b enroll") || fileName.Contains("benefit enrollnent")) //yes, the typo is on purpose. there are typos in some of the file names to import
{
return "benefits-election";
}
//etc 

正如你所能想象的,这种方法丑陋而漫长(大约300行(。我想重构它并利用数据库。我想创建一个包含两个字段DocumentTypeIdFileNameContains的表,其中FileNameContainsOR大小写字符串的逗号分隔列表。这将允许在不做任何代码更改的情况下添加任何案例。

我不确定的是如何在数据库上进行string.Contains()比较。我知道LIKE,但这与string.Contains()不太一样。我还考虑过查询数据库,将FileNameContains字段转换为每个记录的数组或List,并执行一个扩展方法(类似于此(,该方法循环并执行string.Contains()。但这似乎不是很有效和快速。

我是不是搞错了?我只知道必须有一种比一堆else if语句和OR案例更好的方法。我真的认为,拥有一个数据库将使其更加优雅和可扩展,而无需任何代码更改和纯SQLUPDATE语句。如能提供一些帮助和意见,我们将不胜感激。

我会使用字典或keyvaluepair列表。。密钥是";找到这个";,该值为"0";文件类型";

var d = new Dictionary<string, string>{
{ "401k", "401k-and-retirement" }, 
{ "401(k)", "401k-and-retirement" },
{ "457b", "401k-and-retirement" },
{ "457(b)", "401k-and-retirement" },
{ "retire", "401k-and-retirement" },
{ "aflacs", "aflacs" },
...
};
foreach(var kvp in d)
if(filename.Contains(kvp.Key)) return kvp.Value;

在你的列表/dict中添加更多条目,甚至从数据库中填充

我不确定的是如何处理字符串。数据库上的Contains((比较

好吧,你可以将同样的概念传输到数据库中,并将你的值存储在你的表中:

Find, Ret
%401k%, 401k-and-retirement
%401(k)%, 401k-and-retirement

查询类似:

SELECT ret FROM table WHERE @pFilename LIKE Find

带有的c#侧参数

//adjust type and size to match your column
command.Parameters.Add("@pFilename", SqlDbType.VarChar, 50).Value = "my401k.txt";

或者你将在Dapper、EF等中使用的任何等价物。

context.FindRets.FirstOrDefault(fr => EF.Functions.Like(filename, fr.Find))

为了相关神的爱,请不要在表格列中存储CSV。迟早会咬你的

我通常会做这样的事情:

var contains = new []
{
new
{
find = new [] { "401k", "401(k)", "457b", "457(b)", "retire" },
result = "401k-and-retirement"
},
new { find = new [] { "aflac" }, result = "aflac" },
new
{
find = new [] { "beneficiary form", "beneficiaries", "beneficiary" },
result = "beneficiary-forms"
},
new
{
find = new []
{
"benefit enrollment", "benefits enrollment", "benefit form", "benefits form", "benefit paperwork",
"qualifying event", "enrollment", "b enroll", "benefit enrollnent"
},
result = "benefits-election"
},
};
return
contains
.Where(x => x.find.Any(f => fileName.Contains(f)))
.Select(x => x.result)
.FirstOrDefault();

优点是更容易添加和维护您要查找的项目。这一切都在屏幕的一部分。

你可以更进一步,将其保存在一个文本文件中,如下所示:

401k-and-retirement
401k
401(k)
457b
457(b)
retire
aflac
aflac
beneficiary-forms
beneficiary form
beneficiaries
beneficiary
benefits-election
benefit enrollment
benefits enrollment
benefit form
benefits form
benefit paperwork
qualifying event
enrollment
b enroll
benefit enrollnent

然后你可以这样做:

var contains =
File
.ReadLines("config.txt")
.Aggregate(
new[] { new { find = new List<string>(), result = "" } }.ToList(),
(a, x) =>
{
if (x.StartsWith(' '))
{
a.Last().find.Add(x.Substring(1));
}
else
{
a.Add(new { find = new List<string>(), result = x });
}
return a;
}, a => a.Skip(1).ToArray());

contains.Dump();
return
contains
.Where(x => x.find.Any(f => fileName.Contains(f)))
.Select(x => x.result)
.FirstOrDefault();

现在,您可以根据需要向配置文件中添加更多项目。

最新更新