LINQ多连接IQueryable修改结果选择器表达式

mha*_*and 6 c# linq expression entity-framework

想象一下下面的表格结构

---------
TableA
ID
Name

---------
TableB
ID
TableAID

---------
TableC
ID
TableBID
Run Code Online (Sandbox Code Playgroud)

我想定义一个连接这三个表并接受Expression<Func<TableA, TableB, TableC, T>>一个选择器的函数.

所以我想要以下内容:

public IQueryable<T> GetJoinedView<T>(Expression<Func<TableA, TableB, TableC, 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;
}
Run Code Online (Sandbox Code Playgroud)

现在,显然上面没有做我想做的事情,这将给我一个IQueryable表达式类型.我可以使用方法链接语法,但最后我需要多个选择器,每个方法链调用一个.有没有办法采取选择器并将其应用于匿名类型,如下面的不完整函数:

public IQueryable<T> GetJoinedView<T>(Expression<Func<TableA, TableB, TableC, 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);
}
Run Code Online (Sandbox Code Playgroud)

关于如何做到这一点的任何想法?

Oce*_*t20 13

您可以定义一次性中间对象以选择而不是使用匿名类型:

public class JoinedItem
{
    public TableA TableA { get; set; }
    public TableB TableB { get; set; }
    public TableC TableC { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

新方法:

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);
}
Run Code Online (Sandbox Code Playgroud)

你是否真的加入这三个表足以使这个方法的使用更清晰,而不仅仅是在LINQ中直接表达你想要做的事情?我认为每次创建此查询所需的额外行比使用此方法更清晰.