连接来自同一来源的两个 IQueryable 时出现 NotSupportedException

NotSupportedException on concat two IQueryable from same source

见以下代码:

var source = Peoples.AsQueryable();
IQueryable<People> p;
p = source.Where( x => false);
p = p.Concat(source.Where( x => x.FirstName == "DAVID"));
p = p.Concat(source.Where(x => x.City_id == 3));
p.Dump(); //I use linqpad but it does not matter now

此代码有效,并且 linq2sql 产品一 sql-语句(具有三个查询和 UNION ALL)。

现在相同的代码,表面上完全相同的过程,在另一个变体中,抛出 NotSupportedException:

var q = new IQueryableUnderstand<People>(Peoples.AsQueryable());
q.AddToList(x => x.City_id == 3);
q.AddToList(x => x.FirstName == "Dave");
q.Results().Dump();

IQueryableUnderstand Class:

class IQueryableUnderstand<T>
{
    IQueryable<T> _source;
    IQueryable<T> combin;

    public IQueryableUnderstand(IQueryable<T> source)
    {
        _source = source;
        combin = _source.Where(s => false);
    }

    public void AddToList(Func<T, bool> predicate) => combin = combin.Concat(_source.Where(predicate));

    public IQueryable<T> Results() => combin;
}

LINQ To SQL exception: Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains operator

我觉得很傻,有什么区别?

您的 AddToList() 方法接受 Func<T, bool> 谓词。参数类型不正确。如果应用于您的查询,它会将其转换为 Linq-To-Objects 查询。 IQueryable<TSource> 需要表达式,而不是委托。

更改您的方法签名:

public void AddToList(Expression<Func<T, bool>> predicate) =>
    combin = combin.Concat(_source.Where(predicate));