public static IQueryable <QEntity> LeftJoin <QEntity, QKey, JEntity, JKey>( //LeftJoin == + .DefaultIfEmpty() this IQueryable <QEntity> query, LinqToDB.ITable <JEntity> table, Expression <Func <QEntity, QKey> > queryKey, Expression <Func <JEntity, JKey> > joinKey, Expression <Func <QEntity, JEntity> > resultSelectorExpression ) { var joinPropertyInfo = ((PropertyInfo)((MemberExpression)joinKey.Body).Member); var queryParameter = Expression.Parameter(typeof(QEntity), "query"); var joinCollectionParameter = Expression.Parameter(typeof(IQueryable <JEntity>), "joinCollection"); //ex. (l, r) => ... //join => query.ForeignKeyId == (queryType)join.Id var wherePredicate = CreateWherePredicate <QEntity, QKey, JEntity>(queryParameter, queryKey, joinPropertyInfo.Name); var whereCall = CreateWhereCall <JEntity>(joinCollectionParameter, wherePredicate); var defaultIfEmptyMethodInfo = GetDefaultIfEmpty(); var genericDefaultIfEmptyMethodInfo = defaultIfEmptyMethodInfo.MakeGenericMethod(typeof(JEntity)); var defaultIfEmptyCall = Expression.Call(genericDefaultIfEmptyMethodInfo, whereCall); //query => Queryable.Where(joinCollection, join => query.ForeignKeyId == (queryType)join.Id) var collectionSelectorExpression = CreateCollectionSelectorExpression <QEntity, JEntity>(queryParameter, defaultIfEmptyCall); //(queryCollection, joinCollection) => // Queryable.SelectMany(queryCollection, query => // Queryable.Where(joinCollection, join => query.ForeignKeyId == (queryType)join.Id), // (i, j) => i); var expression = CreateExpression(joinCollectionParameter, collectionSelectorExpression, Bind(resultSelectorExpression)); return(expression.Compile()(query, table)); }
public static IQueryable <QEntity> Join <QEntity, QKey, JEntity, JKey>( //LeftJoin == + .DefaultIfEmpty() this IQueryable <QEntity> query, LinqToDB.ITable <JEntity> table, Expression <Func <QEntity, QKey> > queryKey, Expression <Func <JEntity, JKey> > joinKey, Expression <Func <QEntity, JEntity> > resultSelectorExpression ) { var joinPropertyInfo = ((PropertyInfo)((MemberExpression)joinKey.Body).Member); var queryParameter = Expression.Parameter(typeof(QEntity), "query"); var joinCollectionParameter = Expression.Parameter(typeof(IQueryable <JEntity>), "joinCollection"); //ex. (l, r) => ... //join => query.ForeignKeyId == (queryType)join.Id var wherePredicate = CreateWherePredicate <QEntity, QKey, JEntity>(queryParameter, queryKey, joinPropertyInfo.Name); var whereCall = CreateWhereCall <JEntity>(joinCollectionParameter, wherePredicate); //query => Queryable.Where(joinCollection, join => query.ForeignKeyId == (queryType)join.Id) var collectionSelectorExpression = CreateCollectionSelectorExpression <QEntity, JEntity>(queryParameter, whereCall); //var resultBinding = Bind(resultSelectorExpression); //Bind<User, Street>((u, s) => new User { Address = new Address { Street = s }}); //resultSelectorExpression.ToString().Dump(); //resultBinding.ToString().Dump(); //(queryCollection, joinCollection) => // Queryable.SelectMany(queryCollection, query => // Queryable.Where(joinCollection, join => query.ForeignKeyId == (queryType)join.Id), // (i, j) => i); var expression = CreateExpression(joinCollectionParameter, collectionSelectorExpression, Bind(resultSelectorExpression)); //expression.Dump(1); return(expression.Compile()(query, table)); }