Ejemplo n.º 1
0
        private void ProcessFlattenedJoin(GroupJoinClause nonAggregatingJoin, QuerySourceUsageLocator locator)
        {
            var nhJoin = locator.LeftJoin
                                ? new NhOuterJoinClause(nonAggregatingJoin.JoinClause)
                                : (IQuerySource)nonAggregatingJoin.JoinClause;

            // Need to:
            // 1. Remove the group join and replace it with a join
            // 2. Remove the corresponding "from" clause (the thing that was doing the flattening)
            // 3. Rewrite the query model to reference the "join" rather than the "from" clause
            SwapClause(nonAggregatingJoin, (IBodyClause)nhJoin);

            _model.BodyClauses.Remove((IBodyClause)locator.Usages[0]);

            SwapQuerySourceVisitor querySourceSwapper;

            if (locator.LeftJoin)
            {
                // As we wrapped the join clause we have to update all references to the wrapped clause
                querySourceSwapper = new SwapQuerySourceVisitor(nonAggregatingJoin.JoinClause, nhJoin);
                _model.TransformExpressions(querySourceSwapper.Swap);
            }

            querySourceSwapper = new SwapQuerySourceVisitor(locator.Usages[0], nhJoin);
            _model.TransformExpressions(querySourceSwapper.Swap);
        }
		private void ReWrite()
		{
			var aggregateDetectorResults = GetGroupJoinInformation(_groupJoinClauses);

			foreach (var nonAggregatingJoin in aggregateDetectorResults.NonAggregatingClauses)
			{
				// Group joins get processed (currently) in one of three ways.
				// Option 1: results of group join are not further referenced outside of the final projection.
				//           In this case, replace the group join with a join, and add a client-side grouping operator
				//		     to build the correct hierarchy
				//
				// Option 2: Results of group join are only used in a plain "from" expression, such as:
				//                from o in db.Orders
				//                from p in db.Products
				//                join d in db.OrderLines
				//                    on new {o.OrderId, p.ProductId} equals new {d.Order.OrderId, d.Product.ProductId}
				//                    into details
				//                from d in details
				//                select new {o.OrderId, p.ProductId, d.UnitPrice};
				//           In this case, simply change the group join to a join; the results of the grouping are being 
				//           removed by the subsequent "from"
				//
				// Option 3: Results of group join are only used in a "from ... DefaultIfEmpty()" construction, such as:
				//                from o in dc.Orders
				//                join v in dc.Vendors on o.VendorId equals v.Id into ov
				//                from x in ov.DefaultIfEmpty()
				//                join s in dc.Status on o.StatusId equals s.Id into os
				//                from y in os.DefaultIfEmpty()
				//                select new { o.OrderNumber, x.VendorName, y.StatusName }
				//            This is used to repesent an outer join, and again the "from" is removing the hierarchy. So
				//            simply change the group join to an outer join

				_locator = new QuerySourceUsageLocator(nonAggregatingJoin);

				foreach (var bodyClause in _model.BodyClauses)
				{
					_locator.Search(bodyClause);
				}

				if (IsHierarchicalJoin(nonAggregatingJoin))
				{
				}
				else if (IsFlattenedJoin(nonAggregatingJoin))
				{
					ProcessFlattenedJoin(nonAggregatingJoin);
				}
				else if (IsOuterJoin(nonAggregatingJoin))
				{

				}
				else
				{
					// Wonder what this is?
					throw new NotSupportedException();
				}
			}
		}
Ejemplo n.º 3
0
        private void ReWrite()
        {
            var aggregateDetectorResults = GetGroupJoinInformation(_groupJoinClauses);

            foreach (var nonAggregatingJoin in aggregateDetectorResults.NonAggregatingClauses)
            {
                // Group joins get processed (currently) in one of three ways.
                // Option 1: results of group join are not further referenced outside of the final projection.
                //           In this case, replace the group join with a join, and add a client-side grouping operator
                //		     to build the correct hierarchy
                //
                // Option 2: Results of group join are only used in a plain "from" expression, such as:
                //                from o in db.Orders
                //                from p in db.Products
                //                join d in db.OrderLines
                //                    on new {o.OrderId, p.ProductId} equals new {d.Order.OrderId, d.Product.ProductId}
                //                    into details
                //                from d in details
                //                select new {o.OrderId, p.ProductId, d.UnitPrice};
                //           In this case, simply change the group join to a join; the results of the grouping are being
                //           removed by the subsequent "from"
                //
                // Option 3: Results of group join are only used in a "from ... DefaultIfEmpty()" construction, such as:
                //                from o in dc.Orders
                //                join v in dc.Vendors on o.VendorId equals v.Id into ov
                //                from x in ov.DefaultIfEmpty()
                //                join s in dc.Status on o.StatusId equals s.Id into os
                //                from y in os.DefaultIfEmpty()
                //                select new { o.OrderNumber, x.VendorName, y.StatusName }
                //            This is used to repesent an outer join, and again the "from" is removing the hierarchy. So
                //            simply change the group join to an outer join

                _locator = new QuerySourceUsageLocator(nonAggregatingJoin);

                foreach (var bodyClause in _model.BodyClauses)
                {
                    _locator.Search(bodyClause);
                }

                if (IsHierarchicalJoin(nonAggregatingJoin))
                {
                }
                else if (IsFlattenedJoin(nonAggregatingJoin))
                {
                    ProcessFlattenedJoin(nonAggregatingJoin);
                }
                else if (IsOuterJoin(nonAggregatingJoin))
                {
                }
                else
                {
                    // Wonder what this is?
                    throw new NotSupportedException();
                }
            }
        }
Ejemplo n.º 4
0
        private bool IsFlattenedJoin(GroupJoinClause nonAggregatingJoin, QuerySourceUsageLocator locator)
        {
            if (locator.Usages.Count == 1)
            {
                var from = locator.Usages[0] as AdditionalFromClause;

                if (from != null)
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 5
0
 private bool IsHierarchicalJoin(GroupJoinClause nonAggregatingJoin, QuerySourceUsageLocator locator)
 {
     return(locator.Usages.Count == 0);
 }
 private static bool IsHierarchicalJoin(QuerySourceUsageLocator locator)
 {
     return(locator.Usages.Count == 0);
 }
 private static bool IsFlattenedJoin(QuerySourceUsageLocator locator)
 {
     return(locator.Usages.Count == 1 && locator.Usages[0] is AdditionalFromClause);
 }
 private static bool IsOuterJoin(QuerySourceUsageLocator locator)
 {
     return(false);
 }