简体   繁体   English

linq如何通过join和在查询中分隔nhibernate

[英]How linq to nhibernate by join and Separate where in query

I have 3 classes : Person, Employee1 , Employee2 我有3个类:Person,Employee1,Employee2

public class Employee1 : Person
{
}

public class Employee2 : Person
{
}

I need to a query on Person_Table that some time need to join Employee1_Table or Employee_Table. 我需要查询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();
}

This query for join has incomplete. 此连接查询不完整。 If dto.Type equals by PersonType.Employee1 or PersonType.Employee2 , A1 , A2 , ... does not affect. 如果dto.Type等于PersonType.Employee1PersonType.Employee2 ,则A1 , A2 , ...不会影响。 But for default case of switch A1 , A2 , ... has effect on query. 但是对于开关A1 , A2 , ...默认情况,对查询有影响。 My Where conditions in 3 separate classes is many and I need to add Where conditions of query separately. 我在3个单独的类中的Where条件很多,我需要分别添加Where条件的查询。 Why? 为什么?

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>();

This updated query has a exception if B1 condition is true. 如果B1条件为真,则此更新的查询有一个例外。 Message of this exception is : Specified method is not supported. 此异常的消息是: 不支持指定的方法。

Stack Trace is : 堆栈跟踪是:

   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)

In the non-default switch cases, you return q1 and q2, respectively. 在非默认切换情况下,分别返回q1和q2。 These queries are never assigned with anything that involves q, which explains why the Ax conditions aren't present in the final query. 永远不会为这些查询分配任何涉及q的内容,这解释了为什么最终查询中不存在Ax条件的原因。

Also, consider the row: 另外,考虑一下:

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

As with all LINQ methods, the Join method() will not affect q or q1 in any way, but instead return a new IQueryable. 与所有LINQ方法一样,Join方法()不会以任何方式影响q或q1,而是返回一个新的IQueryable。 The code as written ignores this return value, so the line will have no effect on the final query. 写入的代码忽略此返回值,因此该行对最终查询没有影响。

You have the correct pattern everywhere else, that is: "q = q.Something....". 你在其他地方都有正确的模式,即:“q = q.Something ....”。

You will have to change the Join() to return new {x, xx} in its last parameter, so that you can move the .Where() call from q1 to q, and still have access to the item from q1. 您必须更改Join()以在其最后一个参数中返回新的{x,xx},以便您可以将.Where()调用从q1移动到q,并且仍然可以从q1访问该项目。 Something like: 就像是:

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM