/// <summary> /// Include an entity /// </summary> /// <typeparam name="TBaseEntity">The base entity type</typeparam> /// <param name="query">The query</param> /// <param name="joinExpression">The expression to specify the include property /// and join properties, should be something like /// baseEntity => baseEntity.NavigationProperty.JoinProperty = baseEntity.Poperty</param> /// <param name="selectPrefix">The select prefix</param> /// <param name="useLeftJoin">Indicate whether to use left join</param> /// <returns></returns> public BaseDal Include <TBaseEntity>(Query query, Expression <Func <TBaseEntity, bool> > joinExpression, string selectPrefix = "", bool useLeftJoin = false) { var equalExpressions = new MultipleIncludeVisitor() .GetEqualExpressions(joinExpression.Body as BinaryExpression); foreach (var equalExpression in equalExpressions) { var(leftSideProps, rightSideProps, navigationProperty) = new IncludeVisitor() .VisitEqualExpression(joinExpression.Body as BinaryExpression); if (leftSideProps.Contains(navigationProperty)) { // Navigate property is on the left side, swap to make sure the subsequent code works (leftSideProps, rightSideProps) = (rightSideProps, leftSideProps); } var lastRightSideProp = rightSideProps.Last(); var baseTableColumnName = GetColumnName(leftSideProps.Last()); var joinTableColumnName = GetColumnName(lastRightSideProp); var prefixPropName = navigationProperty.Name; selectPrefix = selectPrefix.IsNullOrEmpty() ? prefixPropName : $"{selectPrefix}_{prefixPropName}"; Include(query, baseEntityType: typeof(TBaseEntity), joinEntityType: lastRightSideProp.DeclaringType, selectPrefix: selectPrefix, joinTableColumnName: joinTableColumnName, baseTableColumnName: baseTableColumnName, useLeftJoin: useLeftJoin); } return(this); }
/// <summary> /// Include an entity /// </summary> /// <typeparam name="TBaseEntity">The base entity type</typeparam> /// <typeparam name="TFirstJoinEntity">The first join entity type</typeparam> /// <param name="query">The query</param> /// <param name="joinExpression">The expression to specify the include property /// and join properties, should be something like /// baseEntity => baseEntity.NavigationProperty.JoinProperty = baseEntity.Poperty</param> /// <param name="selectPrefix">The select prefix</param> /// <param name="useLeftJoin">Indicate whether to use left join</param> /// <returns></returns> public BaseDal MultipleInclude <TBaseEntity, TFirstJoinEntity>( Query query, Expression <Func <TBaseEntity, TFirstJoinEntity, bool> > joinExpression, bool useLeftJoin = false) { var visitor = new MultipleIncludeVisitor(); var equalExpressions = visitor.GetEqualExpressions(joinExpression.Body as BinaryExpression); var firstEqualExpression = equalExpressions[0]; var firstFunc = Expression.Lambda <Func <TBaseEntity, bool> >(firstEqualExpression, joinExpression.Parameters.First()); Include(query, firstFunc, useLeftJoin: useLeftJoin); var navigationProperty = visitor.GetNavigationProperty(firstEqualExpression); var secondEqualExpression = equalExpressions[1]; var secondFunc = Expression.Lambda <Func <TFirstJoinEntity, bool> >(secondEqualExpression, joinExpression.Parameters[1]); return(Include(query, secondFunc, navigationProperty.Name, useLeftJoin)); }