如何在C#中使用字符和数字组合搜索两个范围之间的元素

时间:2017-04-21 06:57:34

标签: c# asp.net-mvc nhibernate

我的模块中有一个类似搜索功能的要求,当用户提供输入时,我们需要在两个范围之间进行搜索。

列名称为“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来形成表达式。

2 个答案:

答案 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();
}

此示例使用并需要NH v3.3.3。 CompareTo将被翻译为case when语句。如果您更喜欢使用直接比较,请使用

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