建立真正的动态查询

时间:2019-05-06 07:04:01

标签: c# nhibernate fluent-nhibernate

我有一个基于普通SQL的查询,我想将其转换为一个或多个nHibernate表达式。 SQl表达式如下所示:

string SQL = "SELECT DISTINCT id FROM basetable ";
List<string> conditions...
if( expression_1 ) {
  SQL += "JOIN table_1 ON ...";
  SqlParameters.Add("fooId", _fooId);
}
...
if( expression_n ) {
  SQL += "JOIN table1 ON ...";
  SqlParameters.Add("barId", _barId);
  conditions.Add("field = @barId");
}
...
SQL += "WHERE " + string.Join(" AND ", conditions.ToArray());

结果将是一个巨大的SQL表达式。 有没有机会将这种代码转换为nHibernate表达式?在这种情况下,性能没有意义。

1 个答案:

答案 0 :(得分:1)

这实际上取决于您希望查询具有多大的动态性,但是为了给您一个思路,以下内容相当简单,可以扩展以满足更复杂的要求:

EntityA aAlias = null;
EntityB bAlias = null;
// Build the base query, joining all the tables that you may need
var query = session.QueryOver<EntityA>(() => aAlias)
    .JoinAlias(() => aAlias.ListOfB, () => bAlias);

// Add conditions depending on your requirements, e.g. filter criteria passed from an external source
if (expression1) 
{
    query = query.Where(aAlias.SomeId == someId);
}
if (expression2) 
{
    query = query.WhereRestrictionOn(() => bAlias.SomeOtherId).IsIn(listOfIds)
}
// and so on...
// at the end, just execute the query to get a list of strings or whatever you want
var result = query
    .Select(x => aAlias.Id)
    .List<string>();

根据您的情况,您可以将基础查询的结构(即联接表)放入派生类中,并将共享条件的代码放入基础类中。您只需记住将查询作为参数传递给其他方法时,为Aliases使用相同的变量名。

我们使用类似的方法根据动态搜索条件(包括日期范围,子查询和分页)来构建查询。