问题描述
LinqtoNHibernate没有实现DefaultIfEmpty,没有办法LeftJoin。我想自己实现,参考了其他方法和EF7,还是有点错误。不知道怎么处理了,有没有大神会呢。代码如下:publicclassProcessDefaultIfEmpty:IResultOperatorProcessor<DefaultIfEmptyResultOperator>{publicvoidProcess(DefaultIfEmptyResultOperatordefaultIfEmptyResultOperator,QueryModelVisitorentityQueryModelVisitor,IntermediateHqlTreetree){varqueryModel=entityQueryModelVisitor.Model;varfirstMethod=ReflectionHelper.GetMethodDefinition(()=>Queryable.DefaultIfEmpty<object>((IQueryable<object>)defaultIfEmptyResultOperator.GetConstantOptionalDefaultValue()));vartype=entityQueryModelVisitor.Model.SelectClause.Selector.Type;varparameter=Expression.Parameter(typeof(IQueryable<>).MakeGenericType(type),null);varcall=Expression.Call(firstMethod.MakeGenericMethod(type),parameter);varlambda=Expression.Lambda(call,parameter);tree.AddListTransformer(lambda);}}
解决方案
解决方案二:
EF7和NHibernate都是使用Remotiion.Linq来实现Linq功能的。EF实现代码如下:privatestaticExpressionHandleDefaultIfEmpty(EntityQueryModelVisitorentityQueryModelVisitor,DefaultIfEmptyResultOperatordefaultIfEmptyResultOperator,QueryModelqueryModel){if(defaultIfEmptyResultOperator.OptionalDefaultValue==null){returnExpression.Call(entityQueryModelVisitor.LinqOperatorProvider.DefaultIfEmpty.MakeGenericMethod(entityQueryModelVisitor.StreamedSequenceInfo.ResultItemType),entityQueryModelVisitor.Expression);}varoptionalDefaultValue=entityQueryModelVisitor.ReplaceClauseReferences(defaultIfEmptyResultOperator.OptionalDefaultValue,queryModel.MainFromClause);returnExpression.Call(entityQueryModelVisitor.LinqOperatorProvider.DefaultIfEmptyArg.MakeGenericMethod(entityQueryModelVisitor.StreamedSequenceInfo.ResultItemType),entityQueryModelVisitor.Expression,optionalDefaultValue);}
如上代码所示,EF7会返回一个表达式类型,而NH是向HQL树里追加表达式,现在问题就是出在表达式是什么类型,这一点NH和EF是不一样的。