2013-01-20 21 views
3

我有3类:人,Employee1,和Employee2LINQ如何通过加入NHibernate和独立那里查询

public class Employee1 : Person 
{ 
} 

public class Employee2 : Person 
{ 
} 

我需要在Person_Table的查询一段时间内需要加入Employee1_Table或Employee_Table。

var q = SessionInstance.Query<Person>(); 

if (dto.Code != null)       // A1 Condition 
    q = q.Where(x => x.Code == dto.Code); 

//if(A2 Condition) 
//if(A3 Condition) 
//... 

switch (dto.Type) 
{ 
    case PersonType.Employee1: 
     var q1 = SessionInstance.Query<Employee1>(); 
     q.Join(q1, x => x.Id, xx => xx.Id, (x, xx) => x); 

     if (!String.IsNullOrEmpty(dto.Unit)) // B1 Condition 
      q1 = q1.Where(xx => xx.Unit == dto.Unit); 

     //if(B2 Condition) 
     //if(B3 Condition) 
     //... 

     return q1.ToList<Person>(); 

    case PersonType.Employee2: 
     var q2 = SessionInstance.Query<Employee2>(); 
     q.Join(q2, x => x.Id, xx => xx.Id, (x, xx) => x); 

     if (!String.IsNullOrEmpty(dto.Serial)) // C1 Condition 
      q2 = q2.Where(xx => xx.Serial == dto.Serial); 

     //if(C2 Condition) 
     //if(C3 Condition) 
     //... 

     return q2.ToList<Person>(); 

    default: 
     return q.ToList(); 
} 

此连接查询不完整。如果dto.Type等于PersonType.Employee1PersonType.Employee2,A1 , A2 , ...不会影响。但是对于默认情况下的开关A1 , A2 , ...对查询有影响。 我在哪里条件在3个单独的类是很多,我需要单独添加Where条件的查询。为什么?

UPDATE:

var q = SessionInstance.Query<Person>(); 

if (dto.Code != null)       // A1 Condition 
    q = q.Where(x => x.Code == dto.Code); 

//if(A2 Condition) 
//if(A3 Condition) 
//... 

var q1 = SessionInstance.Query<Employee1>(); 

if (!String.IsNullOrEmpty(dto.Unit)) // B1 Condition 
    q1 = q1.Where(xx => xx.Unit == dto.Unit); 

//if(B2 Condition) 
//if(B3 Condition) 
//... 

return q.Join(q1, x => x.Id, xx => xx.Id, (x, xx) => x).ToList<Person>(); 

此更新的查询有异常,如果B1条件为真。此例外的消息是:不支持指定的方法。

堆栈跟踪是:

at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.GetClassName(IASTNode querySource) 
    at NHibernate.Hql.Ast.ANTLR.PolymorphicQuerySourceDetector.Process(IASTNode tree) 
    at NHibernate.Hql.Ast.ANTLR.AstPolymorphicProcessor.Process() 
    at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory) 
    at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory) 
    at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters) 
    at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow) 
    at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression) 
    at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery) 
    at NHibernate.Linq.NhQueryProvider.Execute[TResult](Expression expression) 
    at Remotion.Data.Linq.QueryableBase`1.GetEnumerator() 
    at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) 
    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) 

回答

6

在非默认开关的情况下,你分别返回Q1和Q2。这些查询不会被分配任何涉及q的内容,这就解释了为什么Ax条件不在最终查询中。

另外,还要考虑该行:

q.Join(q1, x => x.Id, xx => xx.Id, (x, xx) => x); 

与所有LINQ方法,join方法()不会影响Q或Q1以任何方式,而是返回一个新的IQueryable。所写的代码会忽略此返回值,因此该行对最终查询不起作用。

你在其他地方有正确的模式,即:“q = q.Something ....”。

您必须更改Join()以在其最后一个参数中返回新{x,xx},以便您可以将.Where()调用从q1移动到q,并仍然可以访问该项目Q1。类似于:

var qJoined = q.Join(SessionInstance.Query<Employee1>(), 
        x => x.Id, xx => xx.Id, 
        (x, xx) => new {x, xx}); 

if (!String.IsNullOrEmpty(dto.Unit)) // B1 Condition 
    qJoined = qJoined.Where(w => w.xx.Unit == dto.Unit); 

return qJoined.Select(w => w.x).ToList(); 
+0

@Berggren所以我该怎么做? – Ehsan

+0

编辑与如何着手的建议。 –

+0

我在q.Join()之前移动q1.Where(),并返回q.ToList()而不是q1.ToList()。现在q.Where()对查询有影响,但q1不影响。此外,我更改q.Join()q = q.Join(),如果dto.Unit等于null仍然q1.Where不会影响,如果dto.Unit有值,此代码有一个例外,此消息'指定的方法是不支持。' – Ehsan