C# PredicateBuilder 实体:参数“f”;未绑定到指定的 LINQ to Entities 查询表达式中

发布于 2024-09-03 07:57:24 字数 1170 浏览 7 评论 0原文

我需要构建一个动态过滤器,并且我想继续使用实体。由于这个原因,我想使用 albahari 的 PredicateBuilder。

我创建了以下代码:

var invoerDatums = PredicateBuilder.True<OnderzoeksVragen>();
var inner = PredicateBuilder.False<OnderzoeksVragen>();

foreach (var filter in set.RapportInvoerFilter.ToList())
{
    if(filter.IsDate)
    {
        var date = DateTime.Parse(filter.Waarde);
        invoerDatums = invoerDatums.Or(o => o.Van >= date && o.Tot <= date);
    }
    else
    {
        string temp = filter.Waarde;
        inner = inner.Or(o => o.OnderzoekType == temp);
    }
}

invoerDatums = invoerDatums.And(inner);
var onderzoeksVragen = entities.OnderzoeksVragen
                               .AsExpandable()
                               .Where(invoerDatums)
                               .ToList();

当我运行代码时,只有 1 个不是日期过滤器的过滤器。所以只有内部谓词被填充。当执行谓词时,我收到以下错误。

参数“f”未绑定在 指定 LINQ to Entities 查询 表达。

在寻找答案时,我发现了以下内容 页面。但这已经在 LINQKit 中实现了。

还有其他人经历过这个错误并知道如何解决它吗?

I needed to build a dynamic filter and I wanted to keep using entities. Because of this reason I wanted to use the PredicateBuilder from albahari.

I created the following code:

var invoerDatums = PredicateBuilder.True<OnderzoeksVragen>();
var inner = PredicateBuilder.False<OnderzoeksVragen>();

foreach (var filter in set.RapportInvoerFilter.ToList())
{
    if(filter.IsDate)
    {
        var date = DateTime.Parse(filter.Waarde);
        invoerDatums = invoerDatums.Or(o => o.Van >= date && o.Tot <= date);
    }
    else
    {
        string temp = filter.Waarde;
        inner = inner.Or(o => o.OnderzoekType == temp);
    }
}

invoerDatums = invoerDatums.And(inner);
var onderzoeksVragen = entities.OnderzoeksVragen
                               .AsExpandable()
                               .Where(invoerDatums)
                               .ToList();

When I ran the code there was only 1 filter which wasn't a date filter. So only the inner predicate was filled. When the predicate was executed I got the following error.

The parameter 'f' was not bound in the
specified LINQ to Entities query
expression.

While searching for an answer I found the following page. But this is already implemented in the LINQKit.

Does anyone else experienced this error and know how to solve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南巷近海 2024-09-10 07:57:24

我遇到了同样的错误,问题似乎是当我用 PredicateBuilder 创建谓词时,这些谓词又由用 PredicateBuilder 创建的其他谓词组成,

例如 (A OR B) AND (X OR Y),其中一个构建器创建 A OR B ,一个创建 X OR Y,第三个将它们组合在一起。

仅使用一级谓词 AsExpandable 工作得很好,当引入不止一级时,我得到了相同的错误。

我无法找到任何帮助,但通过一些尝试和错误,我能够让事情发挥作用。
每次我调用谓词时,我都会在其后面使用 Expand 扩展方法。

下面是一些代码,为了简单起见,进行了删减:

public static IQueryable<Submission> AddOptionFilter(
    this IQueryable<Submission> query, 
    IEnumerable<IGrouping<int, int>> options)
{
    var predicate = options.Aggregate(
        PredicateBuilder.False<Submission>(),
        (accumulator, optionIds) => accumulator.Or(ConstructOptionMatchPredicate(optionIds).Expand()));
        query = query.Where(predicate.Expand());            
    return query;
}

Query 是一个 IQueryable,它已经调用了 AsExpandable,ConstructOptionNotMatchPredicate 返回一个 Expression。

一旦我们克服了错误,我们当然就能够在运行时针对实体框架构建复杂的过滤器。

编辑:

由于人们仍在评论并投票,我认为它仍然有用,所以我分享另一个修复程序。基本上我已经停止使用 LinqKit,它的谓词构建器支持这个 通用谓词Builder 具有相同的 API,但不需要 Expand 调用,非常值得一试。

I ran across the same error, the issue seemed to be when I had predicates made with PredicateBuilder that were in turn made up of other predicates made with PredicateBuilder

e.g. (A OR B) AND (X OR Y) where one builder creates A OR B, one creates X OR Y and a third ANDs them together.

With just one level of predicates AsExpandable worked fine, when more than one level was introduced I got the same error.

I wasn't able to find any help but through some trial and error I was able to get things to work.
Every time I called a predicate I followed it with the Expand extension method.

Here is a bit of the code, cut down for simplicity:

public static IQueryable<Submission> AddOptionFilter(
    this IQueryable<Submission> query, 
    IEnumerable<IGrouping<int, int>> options)
{
    var predicate = options.Aggregate(
        PredicateBuilder.False<Submission>(),
        (accumulator, optionIds) => accumulator.Or(ConstructOptionMatchPredicate(optionIds).Expand()));
        query = query.Where(predicate.Expand());            
    return query;
}

Query is an IQueryable which has already had AsExpandable called, ConstructOptionNotMatchPredicate returns an Expression.

Once we got past the error we were certainly able to build up complicated filters at runtime against the entity framework.

Edit:

Since people are still commenting on and up voting this I assume it is still useful so I am sharing another fix. Basically I have stopped using LinqKit and it's predicate builder in favour of this Universal Predicate Builder that has the same API but doesn't need Expand calls, well worth checking out.

海未深 2024-09-10 07:57:24

我收到此错误,Mant101 的解释给了我答案,但您可能正在寻找导致问题的更简单的示例:

// This predicate is the 1st predicate builder
var predicate = PredicateBuilder.True<Widget>();

// and I am adding more predicates to it (all no problem here)
predicate = predicate.And(c => c.ColumnA == 1);
predicate = predicate.And(c => c.ColumnB > 32);
predicate = predicate.And(c => c.ColumnC == 73);

// Now I want to add another "AND" predicate which actually comprises 
// of a whole list of sub-"OR" predicates
if(keywords.Length > 0)
{
    // NOTICE: Here I am starting off a brand new 2nd predicate builder....
    // (I'm not "AND"ing it to the existing one (yet))
    var subpredicate = PredicateBuilder.False<Widget>();

    foreach(string s in keywords)
    {
        string t = s;  // s is part of enumerable so need to make a copy of it
        subpredicate = subpredicate.Or(c => c.Name.Contains(t));
    }

    // This is the "gotcha" bit... ANDing the independent
    // sub-predicate to the 1st one....

    // If done like this, you will FAIL!
//  predicate = predicate.And(subpredicate); // FAIL at runtime!

    // To correct it, you must do this...
    predicate = predicate.And(subpredicate.Expand());  // OK at runtime!
}

希望这有帮助! :-)

I got this error and Mant101's explanation got me the answer, but you might be looking for a simpler example that causes the problem:

// This predicate is the 1st predicate builder
var predicate = PredicateBuilder.True<Widget>();

// and I am adding more predicates to it (all no problem here)
predicate = predicate.And(c => c.ColumnA == 1);
predicate = predicate.And(c => c.ColumnB > 32);
predicate = predicate.And(c => c.ColumnC == 73);

// Now I want to add another "AND" predicate which actually comprises 
// of a whole list of sub-"OR" predicates
if(keywords.Length > 0)
{
    // NOTICE: Here I am starting off a brand new 2nd predicate builder....
    // (I'm not "AND"ing it to the existing one (yet))
    var subpredicate = PredicateBuilder.False<Widget>();

    foreach(string s in keywords)
    {
        string t = s;  // s is part of enumerable so need to make a copy of it
        subpredicate = subpredicate.Or(c => c.Name.Contains(t));
    }

    // This is the "gotcha" bit... ANDing the independent
    // sub-predicate to the 1st one....

    // If done like this, you will FAIL!
//  predicate = predicate.And(subpredicate); // FAIL at runtime!

    // To correct it, you must do this...
    predicate = predicate.And(subpredicate.Expand());  // OK at runtime!
}

Hope this helps! :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文