请问Linq多表混合联查要如何写?Nhbiernate left join linq

sby5104 2017-04-29 05:18:09
---------------------2017.4.30 update------------------------
http://stackoverflow.com/questions/42410867/nhibernate-left-join-with-linq
根据查询结果来看, 目前的linq-to-nhibernate 不支持left join 啊.

先结贴了, 如果哪位有linq-to-nhibernate 的限制总结, 或者文档, 可以麻烦你发下链接吗
先谢谢了

------------------------

需要实现的结果是下面这个sql, 用前面合成的大表在left join 最后一张表,

SELECT *
FROM ActivityDetail d
join Activity a on d.ActivityId = a.Id
join Product p on d.ProductId = p.Id
join Purpose pu on a.PurposeId = pu.Id
left outer join Signature s on s.ActivityId = a.Id


请问将他转成sql 要怎么写呢?
试了几种方法一直在报错.

请问以下写法有什么问题吗?

var testQuery = from detail in ActivityDetailRepository.Table
join activity in ActivityRepository.Table on detail.ActivityId equals activity.Id into d_a
from da in d_a.DefaultIfEmpty()
join product in ProductRepository.Table on detail.ProductId equals product.Id into d_a_prodcut
from dap in d_a_prodcut.DefaultIfEmpty()
join purpose in PurposeRepository.Table on da.PurposeId equals purpose.Id into d_a_p_p
from dapp in d_a_p_p.DefaultIfEmpty()
join signautre in SignatureRepository.Table on detail.ActivityId equals signautre.ActivityId into final
from f in final.DefaultIfEmpty()
select new
{
ActivityId = da.Id,
ProductName = dap.ProductName,
PurposeName = dapp.PurposeName,
....
};
var testlist = testQuery.Skip(0).Take(100).ToList();



报错如下
System.NotImplementedException”类型的异常在 NHibernate.dll 中发生,但未在用户代码中进行处理

在 NHibernate.Linq.CacheableExpressionNode.Resolve(ParameterExpression inputParameter, Expression expressionToBeResolved, ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.IntermediateModel.ExpressionResolver.GetResolvedExpression(Expression unresolvedExpression, ParameterExpression parameterToBeResolved, ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.IntermediateModel.JoinExpressionNode.<>c__DisplayClass1.<GetResolvedOuterKeySelector>b__0(ExpressionResolver r)
在 Remotion.Linq.Parsing.Structure.IntermediateModel.ResolvedExpressionCache`1.GetOrCreate(Func`2 generator)
在 Remotion.Linq.Parsing.Structure.IntermediateModel.JoinExpressionNode.GetResolvedOuterKeySelector(ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.IntermediateModel.JoinExpressionNode.CreateJoinClause(ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.IntermediateModel.GroupJoinExpressionNode.ApplyNodeSpecificSemantics(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.IntermediateModel.MethodCallExpressionNodeBase.Apply(QueryModel queryModel, ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.QueryParser.ApplyAllNodes(IExpressionNode node, ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.QueryParser.ApplyAllNodes(IExpressionNode node, ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.QueryParser.ApplyAllNodes(IExpressionNode node, ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.QueryParser.ApplyAllNodes(IExpressionNode node, ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.QueryParser.ApplyAllNodes(IExpressionNode node, ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.QueryParser.ApplyAllNodes(IExpressionNode node, ClauseGenerationContext clauseGenerationContext)
在 Remotion.Linq.Parsing.Structure.QueryParser.GetParsedQuery(Expression expressionTreeRoot)
在 NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory, Boolean filter)
在 NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
在 NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
在 NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
在 NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
在 NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
在 NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
在 NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
在 Remotion.Linq.QueryableBase`1.GetEnumerator()
在 System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
在 System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
在 lambda_method(Closure , ControllerBase , Object[] )
在 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
在 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
在 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
在 System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
在 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
在 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
在 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
在 System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
在 System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
...全文
1934 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
sby5104 2017-04-30
  • 打赏
  • 举报
回复

var t1 = from d in (from detail in ActivityDetailRepository.Table
                                join activity in ActivityRepository.Table on detail.ActivityId equals activity.Id
                                join product in ProductRepository.Table on detail.ProductId equals product.Id
                                join purpose in PurposeRepository.Table on activity.PurposeId equals purpose.Id
                                select new
                                {
                                    detail = detail,
                                    activity = activity,
                                    product = product,
                                    purpose = purpose,
                                })
                     join signautre in SignatureRepository.Table on d.activity.Id equals signautre.ActivityId into temp
                     from t in temp.DefaultIfEmpty()
                     select new
                     {
                         ActivityId = d.activity.Id,
                         ProductName = d.product.ProductName,
                         PurposeName = d.purpose.PurposeName,
                         CurrentProductPensTotalCount = d.detail.CurrentProductPensTotalCount,
                         PensDetailList = d.detail.PensDetailList,
                         CreatedDate = d.activity.CreatedDate,
                         UpdatedDate = d.activity.UpdatedDate,
                         PensTotalCount = d.activity.PensTotalCount,
                         Signautre = t.Signature,
                     };
依然报错 无法将类型为“Remotion.Linq.Clauses.JoinClause”的对象强制转换为类型“Remotion.Linq.Clauses.FromClauseBase”
sby5104 2017-04-29
  • 打赏
  • 举报
回复
尝试的另外一种方法:

var testQuery2 = from detail in DetailRepository.Table
                             join activity in ActivityRepository.Table on detail.ActivityId equals activity.Id
                             join product in ProductRepository.Table on detail.ProductId equals product.Id
                             join purpose in PurposeRepository.Table on activity.PurposeId equals purpose.Id
                             join signature in rSignatureRepository.Table on activity.Id equals signature.ActivityId into temp
                             from t in temp.DefaultIfEmpty()
                             select new
                            {
                                ActivityId = activity.Id,
                                ProductName = product.ProductName,
                                PurposeName = purpose.PurposeName,
                                CreatedDate = activity.CreatedDate,
                                UpdatedDate = activity.UpdatedDate,
                                PensTotalCount = activity.PensTotalCount,
                             .......
                            };
error: System.InvalidCastException”类型的异常在 NHibernate.dll 中发生,但未在用户代码中进行处理 其他信息: 无法将类型为“Remotion.Linq.Clauses.JoinClause”的对象强制转换为类型“Remotion.Linq.Clauses.FromClauseBase
sby5104 2017-04-29
  • 打赏
  • 举报
回复
还尝试了一种方法, 就是将这个linq 拆成两个, leftTable 和 signatureTable 但是在执行的时候必须将leftTable ToList() 之后才能执行, 否则会报一个错, From不能转成Join 这样的 代码大概如下

var leftTable = from detail in DetailRepository.Table
                            join activity in ActivityRepository.Table on detail.ActivityId equals activity.Id
                            join product in Repository.Table on detail.ProductId equals product.Id
                            join purpose in PurposeRepository.Table on activity.PurposeId equals purpose.Id
                            select new
                            {
                                ActivityId = activity.Id,
                                ProductName = product.ProductName,
                                PurposeName = purpose.PurposeName,
                                CreatedDate = activity.CreatedDate,
                                UpdatedDate = activity.UpdatedDate,
                                PensTotalCount = activity.PensTotalCount,
                             .......
                            };
var finalQuery = from left in leftTable
                             join signature in SignatureRepository.Table on left.ActivityId equals signature.ActivityId into temp
                             from s in temp.DefaultIfEmpty()
                             select new
                             {
                                 .......
                             };

错误如下: System.InvalidCastException”类型的异常在 NHibernate.dll 中发生,但未在用户代码中进行处理 其他信息: 无法将类型为“Remotion.Linq.Clauses.JoinClause”的对象强制转换为类型“Remotion.Linq.Clauses.FromClauseBase

   在 NHibernate.Linq.GroupJoin.GroupJoinAggregateDetectionVisitor.VisitQuerySourceReferenceExpression(QuerySourceReferenceExpression expression)
   在 Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression)
   在 NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression)
   在 Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberExpression(MemberExpression expression)
   在 NHibernate.Linq.GroupJoin.GroupJoinAggregateDetectionVisitor.VisitMemberExpression(MemberExpression expression)
   在 Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression)
   在 NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression)
   在 Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitAndConvert[T](T expression, String methodName)
   在 Remotion.Linq.Parsing.ExpressionTreeVisitor.<>c__DisplayClass6`1.<VisitAndConvert>b__5(T expression)
   在 Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)
   在 Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitAndConvert[T](ReadOnlyCollection`1 expressions, String callerName)
   在 Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitNewExpression(NewExpression expression)
   在 Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression)
   在 NHibernate.Linq.Visitors.NhExpressionTreeVisitor.VisitExpression(Expression expression)
   在 NHibernate.Linq.GroupJoin.GroupJoinAggregateDetectionVisitor.Visit(IEnumerable`1 groupJoinClause, Expression selectExpression)
   在 NHibernate.Linq.GroupJoin.AggregatingGroupJoinRewriter.IsAggregatingGroupJoin(QueryModel model, IEnumerable`1 clause)
   在 NHibernate.Linq.GroupJoin.AggregatingGroupJoinRewriter.ReWrite(QueryModel model)
   在 NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)
   在 NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory, Boolean filter)
   在 NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
   在 NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
   在 NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
   在 NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
   在 NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
   在 NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
   在 NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
   在 Remotion.Linq.QueryableBase`1.GetEnumerator()
   在 System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   在 System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   在 iDoctor.O2O.Service.FreePenService.GetActivityList(String userId, Int32 activityId, FreePenQueryParameter para)
   在 iDoctor.O2O.Service.FreePenService.GetActivityDetailById(String userId, Int32 activityId)
   在 iDoctor.O2O.Controllers.InterfaceController.GetActivityDetailById(String userId, Int32 activityId)
   在 lambda_method(Closure , ControllerBase , Object[] )
   在 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
   在 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   在 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   在 System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
   在 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
   在 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   在 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
   在 System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
   在 System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
DNetORM源码 源码描述: 一、源码介绍 1、DNetORM 是一款基于.net的轻量级的、轻配置的ORM框架,核心代码只有100K大小,支持SQLSERVER、MYSQL、ORACLE数据库,DNetORM的核心思想是,将最接近原生的C#代码映射出最符合场景的sql语句,从而最大程度提升开发效率。 2、为什么要开发一款orm框架,笔者在开发的这些年里,使用了很多框架,有第三方的譬如mybatis、nhibernate、ef等等,但是它们都不符合我的开发习惯,首先我喜欢轻配置,不喜欢将大量的sql语句在配置文件里,也不喜欢将实体映射关系在配置文件里,所以像mybatis、nhibernate这种重配置的orm我并不喜欢,EF算是一个功能强大的框架,但是EF也有一些缺陷,过于笨重,另外EF对于mysql、oracle的支持并不友好。另外还有一些其他框架接口封装的不友好、要么法过于繁琐、要么接口不清晰,这些因素都是促使我一个符合我的开发场景的orm 3、DNetORM使用起来非常简单,DNetORM拒绝封装过多的方法,这会造成使用的难度,只是封装了增删改查基本常用的一些方法,所以使用起来会非常简单。 4、DNetORM对于多表联查进行了常规的封装支持了LEFT JOIN, INNER JOIN ,GROUP BY , ORDER BY, WHERE,对于复杂的法,建议使用DNetORM提供的SQL查询接口,我们在开发中使用orm是为了提升开发效率,节省开发时间,这是为什么使用orm的目的,orm不是为了避免使用sql,实际开发中有很多查询语句会很复杂,如果依赖orm,首先orm即使支持的话也会的很复杂,并不直观,以往有开发的筒子们在用linq实现相同的复杂一点的sql的时候,个sql也就是5分钟,但是为了实现linq了半小时,还的不正确,所以这些都是违背开发精神的。所以ORM是一个开发工具,它的出现就是为了节省开发时间、提升开发效率,使用orm可以帮你解决增删改的繁杂琐事,在查询上,orm帮你处理了大部分的单表查询,在多表的查询上,orm帮你处理简单的多表查询,帮你最快的获取数据,至于复杂的sql查询,直接使用sql查询接口。也许这种做法更加合理。 二、注意事项 1、开发环境为Visual Studio 2015,使用.net 4.0开发。

8,497

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 LINQ
社区管理员
  • LINQ
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧