我的模块中有一个类似搜索功能的要求,当用户提供输入时,我们需要在两个范围之间进行搜索。
列名称为“Name”,在Oracle 11G DB中定义为varchar
UI列名称为NAME。
示例列名称:A5000C0,A5000C2,A5000C3,A5000C4,A5000C5,A5000C6
因此,当用户尝试使用A5000C0- A5000C6等名称字段范围进行搜索时,结果应为A5000C1至A5000C6范围内的元素。
PS:有些情况下用户可以在A5000C1到A5001C6范围内进行搜索
如何在C#中执行此操作?我们的模块基于ASP.Net MVC5使用c#和搜索表达式,我们使用NHibernate来形成表达式。
答案 0 :(得分:1)
我看到你的问题被删除了。如果您愿意,请试用此代码。它已转换为C#,但您在使用它之前应该仔细查看它。
public static HashSet<string> GetNamesFromRangeQuery(string multipleIds)
{
multipleIds = multipleIds.ToUpper().Replace(" ", "");
HashSet<string> inSet = new HashSet<string>();
string[] parts = multipleIds.Split(new[] { ";" }, StringSplitOptions.None);
foreach (string part in parts)
{
Regex rgx = new Regex(@"^M([0 - 9] +)C([0 - 9] +)$");
Regex rgxTwo = new Regex(@"^M([0-9]+)C([0-9]+)-M([0-9]+)C([0-9]+)$");
Regex rgxThree = new Regex(@"^[0-9]+$");
Regex rgxFour = new Regex(@"^([0-9]+)-([0-9]+)$");
if (rgx.IsMatch(part))
{
inSet.Add(part);
}
else if (rgxTwo.IsMatch(part))
{
string[] fromTo = part.Split(new[] { "-" }, StringSplitOptions.None);
int mFrom = int.Parse(fromTo[0].Substring(1, fromTo[0].IndexOf("C")));
int mTo = int.Parse(fromTo[1].Substring(1, fromTo[1].IndexOf("C")));
int cFrom = int.Parse(fromTo[0].Substring(fromTo[0].LastIndexOf("C") + 1));
int cTo = int.Parse(fromTo[1].Substring(fromTo[1].LastIndexOf("C") + 1));
for (int i = mFrom; i <= mTo; i++)
{
for (int j = cFrom; j <= cTo; j++)
{
inSet.Add("M" + i + "C" + j);
}
}
}
else if (rgxThree.IsMatch(part))
{
inSet.Add(part);
}
else if (rgxFour.IsMatch(part)
{
string[] fromTo = part.Split(new[] { "-" }, StringSplitOptions.None);
int from = int.Parse(fromTo[0]);
int to = int.Parse(fromTo[1]);
for (int i = from; i <= to; i++)
{
inSet.Add(i.ToString());
}
}
else
{
inSet.Add(part);
}
}
return inSet;
}
答案 1 :(得分:0)
我不确定我明白这一点。它看起来像一个按字母顺序排列的字符串比较,不是吗?
所以这样的事情应该这样做:
public IList<Entity> SearchRange(string lower, string upper)
{
return _session.Query<Entity>()
.Where(e => e.Name.CompareTo(lower) >= 0 and e.Name.CompareTo(upper) <= 0)
.ToList();
}
此示例使用linq-to-nhibernate并需要NH v3.3.3。 CompareTo
将被翻译为case when
语句。如果您更喜欢使用直接比较,请使用hql:
public IList<Entity> SearchRange(string lower, string upper)
{
return _session
.CreateQuery("from Entity e where e.Name between :lower and :upper")
.SetString("lower", lower)
.SetString("upper", upper)
.List<Entity>();
}
HQL查询也可以写成from Entity e where e.Name >= :lower and e.Name <= :upper
。