This may not be the solution you are looking for, but I will post it:
I would recommend a DataModel for every “selection” you make in your database, for example:
public class JoinedDataModel { public TableA DataA { get; set; } public TableB DataB { get; set; } public TableC DataC { get; set; } }
your 'select' does what you already do
public IQueryable<JoinedDataModel> GetJoinedView( ) { return from a in DbContext.Set<TableA>() join b on DbContext.Set<TableB>() a.ID equals b.TableAID join c on DbContext.Set<TableC>() b.ID equals c.TableBID select new JoinedDataModel( ) { DataA = a, DataB = b, DataC = c }; }
and then you need some kind of “mapper” that represents your “selector”, or at least what you think you have in the selector:
public static Mapper( ) { private static Dictionary<MapTuple, object> _maps = new Dictionary<MapTuple, object>(); public static void AddMap<TFrom, TTo>(Action<TFrom, TTo, DateTime> map) { Mapper._maps.Add(MapTuple.Create(typeof(TFrom), typeof(TTo)), map); } public static TTo Map<TFrom, TTo>( TFrom srcObj ) { var typeFrom = typeof(TFrom); var typeTo = typeof(TTo); var key = MapTuple.Create(typeFrom, typeTo); var map = (Action<TFrom, TTo, DateTime>) Mapper._maps[key]; TTo targetObj = new TTo( ); map( srcObj, targetObj ); return targetObj; }
then you need to define at least one matching method:
AddMap<JoinedDataModel, YourResultModel>( ( src, trg ) => { trg.SomePropertyA = src.DataA.SomeProperty; trg.SomePropertyB = src.DataB.SomeProperty; } );
then you can just call:
public IList<YourResultModel> CallDb( ) { return ( from item in GetJoinedView( ) select Mapper.MapTo<JoinedDataModel, YourResultModel>( item ) ).ToList( ); }
I know that you want to pass some kind of Expression into a method, but I think that this will not work, but maybe someone came up with a solution.