如何使用nhibernate进行正确的搜索

时间:2010-05-27 16:57:43

标签: c# nhibernate search

我正在开发一个小型项目,该项目应该允许对数据库进行基本搜索。 目前我正在使用nhibernate进行数据库交互。 在数据库中,我有2个表:人员和地址。 Person表与Address具有多对一关系。

我提出的搜索代码是:

public IList<T> GetByParameterList(List<QueryParameter> parameterList)
    {
        if (parameterList == null)
        {
            return GetAll();
        }
        using (ISession session = NHibernateHelper.OpenSession())
        {
            ICriteria criteria = session.CreateCriteria<T>();
            foreach (QueryParameter param in parameterList)
            {
                switch (param.Constraint)
                {
                    case ConstraintType.Less:
                        criteria.Add(Expression.Lt(param.ParameterName, param.ParameterValue));
                        break;
                    case ConstraintType.More:
                        criteria.Add(Expression.Gt(param.ParameterName, param.ParameterValue));
                        break;
                    case ConstraintType.LessOrEqual:
                        criteria.Add(Expression.Le(param.ParameterName, param.ParameterValue));
                        break;
                    case ConstraintType.EqualOrMore:
                        criteria.Add(Expression.Ge(param.ParameterName, param.ParameterValue));
                        break;
                    case ConstraintType.Equals:
                        criteria.Add(Expression.Eq(param.ParameterName, param.ParameterValue));
                        break;
                    case ConstraintType.Like:
                        criteria.Add(Expression.Like(param.ParameterName, param.ParameterValue));
                        break;
                }
            }

            try
            {
                IList<T> result = criteria.List<T>();
                return result;
            }
            catch
            {
                //TODO: Implement some exception handling
                throw;
            }
        }
    }

查询参数是一个帮助对象,我用它来创建标准并将其发送到dal,它看起来像这样:

public class QueryParameter
{
    public QueryParameter(string ParameterName, Object ParameterValue, ConstraintType constraintType)
    {
        this.ParameterName = ParameterName;
        this.ParameterValue = ParameterValue;
        this.Constraint = constraintType;
    }

    public string ParameterName
    {
        get;
        set;
    }

    public Object ParameterValue
    {
        get;
        set;
    }

    public ConstraintType Constraint
    {
        get;
        set;
    }
}

现在,如果我正在进行像FirstName =“John”这样的搜索,这种情况很有效,但是当我尝试给出像Street =“Some Street”这样的参数时,这种效果并不好。似乎nhibernate正在Person表中寻找街道列而不是在Address表中。

我应该如何更改代码,以便我可以进行正确的搜索?提示?也许有一些替代方案?

免责声明:我有点像菜鸟,所以请温柔;) 谢谢,丹尼斯。

4 个答案:

答案 0 :(得分:1)

我会为每个域对象类做一个强类型搜索类(例如,使用针对我的域对象的代码生成)。

我会有一个抽象类,使用非常接近当前代码的东西放置ICriteriaBuilder逻辑,然后对任何内部ICriteriaBuilder属性进行递归。

我会有类似伪代码的东西:

class SearchCriteriaBuilder
public ConstraintType constraintType
public ICriteria Build(ISearchCriteriaBuilder pSearchCriteria)
{'your code goes there'}

class AdressSearchCriteriaBuilder : SearchCriteriaBuilder
public StringSearchCriteriaBuilder street;
public IntegerSearchCriteriaBuilder number;

class PersonSearchCriteriaBuilder : SearchCriteriaBuilder
public StringSearchCriteriaBuilder name;
public AdressSearchCriteriaBuilder adress;

答案 1 :(得分:0)

您可以像这样使用hql查询

from Person p join Address a where a.Street = :street

并使用查询设置:street参数。

我发现使用hql比处理标准内容要容易得多,尤其是当你是新手时。你的第一直觉是标准化你的nhibernate用法,但是当你学习它时,最好让你的代码接近nhibernate API而不是编写太多辅助方法。

答案 2 :(得分:0)

正在寻找Person实体中的Street属性(注意ORM语言......没有表和列;-))因为这一行:

ICriteria criteria = session.CreateCriteria<T>();

我假设您的类型T是Person,因此您的条件假定您添加的约束引用Person中的属性。

如果您传入的参数是地址实体上的过滤器,则需要调用CreateAlias(...)以“加入”地址。

答案 3 :(得分:0)

请在1:57查看此视频:http://skillsmatter.com/podcast/open-source-dot-net/nhibernate-tutorial-by-ayende-rahien

Ayende(最着名的nhibernate专家)告诉你如何使用标准api构建动态查询。

请注意2:04:30发布的foreach解释