如何在使用多个源表时重用"Where"的linq表达式

tym*_*tam 7 c# linq

我们有以下内容:

public interface IOne {
    UInt64 Id { get; }
    Int16 Size { get; }
}

public interface ITwo {
    UInt64 OneId { get; }
    Int16 Color { get; }
}
Run Code Online (Sandbox Code Playgroud)

正如这里所解释的,重用linq表达式的方法是编写如下内容:

public static Expression<Func<IOne, bool>> MyWhereExpression( int value ){
    return (o) => (o.Size > value);
}

int v = 5;
IQueryable<IOne> records = from one in s.Query<IOne>()
                                        .Where(MyWhereExpression(v))
                           select one;
Run Code Online (Sandbox Code Playgroud)

当我想对两张桌子做同样的事情时,我遇到了一个问题.

表达方式:

public static Expression<Func<IOne, ITwo, bool>> MyWhereExpression2(int color ) {
    return (one,two) => (one.Id == two.OneId) && (two.Color > color );
}
Run Code Online (Sandbox Code Playgroud)

Linq 1:

int color = 100;
IQueryable<IOne> records = from one in s.Query<IOne>()
                           from two in s.Query<ITwo>()
                                        .Where(MyWhereExpression2(color))
                           select one;
Run Code Online (Sandbox Code Playgroud)

这不起作用.只有第二个来自.

Linq 2:

int color = 100;
IQueryable<IOne> records = (from one in s.Query<IOne>()
                            from two in s.Query<ITwo>()
                            select new { one, two })
                           .Where(MyWhereExpression2(color));
Run Code Online (Sandbox Code Playgroud)

这导致了

参数2:无法从'Expression <System.Func <IOne,ITwo,bool >>'转换为'System.Func <AnonymousType#1,int,bool>'

我理解有关AnonymousType的错误消息,但我无法弄清楚如何编写查询.

我之所以要使用表达式而不是只是写

where (one.Id == two.OneId) && (two.Color > color ) 
Run Code Online (Sandbox Code Playgroud)

直接在linq查询中是因为我想在多个linq查询中重用此表达式.

tym*_*tam 1

回答我自己的问题...

经过一些实验(包括 Nick Guerrera 的原始答案),我采取了另一种方法 - 我没有尝试重用表达式,而是重用了整个 linq。然而,它仍然需要创建一个容器结构。

struct Pair {
    public IOne One { get; set; }
    public ITwo Two { get; set; }
    public Pair(IOne one, ITwo two) : this() {
        One = one;
        Two = two;
    }
}


public IQueryable<Pair> Get(ISession s, int color) {
            return from one in s.Query<IOne>()
                   from two in s.Query<ITwo>()
                   where (one.Id == two.OneId) && (two.Color > color)
                   select new Pair(one, two);
        }
Run Code Online (Sandbox Code Playgroud)

现在我可以打电话

Get(s, color).Count();
Run Code Online (Sandbox Code Playgroud)

var records = (from data in Get(s, color) select data).Take(2000);
Run Code Online (Sandbox Code Playgroud)

ETC。