通用数据网格过滤

时间:2011-01-06 11:32:18

标签: nhibernate hibernate fluent-nhibernate

我一直致力于使用Nhibernate过滤数据的通用解决方案。代码如下所示:

private ICriteria GetPagedCriteria<T>(GridResult<T> GridResult, bool sort)
        {
            var query = Session.CreateCriteria(typeof(T));

            foreach (string alias in GridResult.NHibernatePaths)
            {
                query.CreateAlias(alias, alias.Replace(".", "_"));
            }

            foreach (PropertyValueOperators pvo in GridResult.FilterList)
            {
                if(String.IsNullOrEmpty(pvo.Value) == false)
                {
                    switch (pvo.LikeOperator)
                    {
                        case "Contains":
                            query.Add(Expression.InsensitiveLike(Projections.Cast(NHibernateUtil.String, Projections.Property(pvo.Property)), String.Format("%{0}%",pvo.Value), MatchMode.Exact));
                        break;
                        case "EndsWith":
                            query.Add(Expression.InsensitiveLike(Projections.Cast(NHibernateUtil.String, Projections.Property(pvo.Property)), String.Format("%{0}", pvo.Value), MatchMode.Exact));
                        break;
                        case "Equals":
                            query.Add(Expression.InsensitiveLike(Projections.Cast(NHibernateUtil.String, Projections.Property(pvo.Property)), pvo.Value, MatchMode.Exact));
                        break;
                        case "Starts With":
                            query.Add(Expression.InsensitiveLike(Projections.Cast(NHibernateUtil.String, Projections.Property(pvo.Property)), String.Format("{0}%", pvo.Value), MatchMode.Exact));
                        break;
                        default:
                            throw new ArgumentException("LikeOperator not recognised");
                    }
                }
            }

            if (sort)
            {
                foreach (var pair in GridResult.SortList)
                {
                    var func = pair.Value
                       ? new Func<string, NHibernate.Criterion.Order>(NHibernate.Criterion.Order.Asc)
                       : new Func<string, NHibernate.Criterion.Order>(NHibernate.Criterion.Order.Desc);
                    query.AddOrder(func(pair.Key));
                }
            }

            return query;
        }

不幸的是,这会产生很多“喜欢”和“强制转换”的SQL,效率非常低。据我所知,我知道......我还不是NHibernate的专家,所以我希望任何评论能让这个通用解决方案更有效率。非常感谢提前。

基督教

2 个答案:

答案 0 :(得分:2)

在你的情况下,如何避免使用like运算符。 好吧,平等操作员很简单, “以”转换为“喜欢'值'%'的”开头“也是有效的,因为它是左侧匹配并且它可以使用索引, “包含”和“以...结尾”必须转换为您已经实施的类似操作。

如果你真的想避免基于类似的搜索,你必须改变你的方法 - 不要使用CriteriaAPI并将Lucene.NET与NHibernate.Search结合使用,这可能会更好地满足你的需求。我没有在生产项目中使用它们,但它们看起来很完美。

答案 1 :(得分:1)

包含,Endswith和Startswith无法在没有类似的情况下转换为sql中的类似内容。 sql数据库不适合这类查询。您可以更好地使用像Lucene这样的搜索数据库,结合NHiberante.Search