想象一下下面的表格结构
--------- TableA ID Name --------- TableB ID TableAID --------- TableC ID TableBID
我想定义一个连接这三个表并接受表达式< Func< TableA,TableB,TableC,T>>的函数.作为选择器.
所以我想要以下内容:
public IQueryable<T> GetJoinedView<T>(Expression<Func<TableA,T>> selector) { 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 selector; }
现在,显然上面没有做我想做的事情,这将给我一个表达类型的IQueryable.我可以使用方法链接语法,但最后我需要多个选择器,每个方法链调用一个.有没有办法采取选择器并将其应用于匿名类型,如下面的不完整函数:
public IQueryable<T> GetJoinedView<T>(Expression<Func<TableA,T>> selector) { var query = 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 { A = a,B = b,C = c }; // I need the input selector to be modified to be able to operate on // the above anonymous type var resultSelector = ModifyInputSelectorToOperatorOnAnonymousType(selector); return query.Select(resultSelector); }
关于如何做到这一点的任何想法?
解决方法
您可以定义一次性中间对象以选择而不是使用匿名类型:
public class JoinedItem { public TableA TableA { get; set; } public TableB TableB { get; set; } public TableC TableC { get; set; } }
新方法:
public IQueryable<T> GetJoinedView<T>(Expression<Func<JoinedItem,T>> selector) { return DbContext.Set<TableA>() .Join(DbContext.Set<TableB>(),a => a.ID,b => b.TableAID,(ab) => new { A = a,B = b}) .Join(DbContext.Set<TableC>(),ab => ab.B.ID,c => c.TableBID (ab,c) => new JoinedItem { TableA = ab.A,TableB = ab.B,TableC = c }) .Select(selector); }
你是否真的加入这三个表足以使这个方法的使用更清晰,而不仅仅是在LINQ中直接表达你想要做的事情?我认为每次创建此查询所需的额外行比使用此方法更清晰.