简体   繁体   English

如何选择表达式的评估值 <Func<T> &gt;在实体框架查询中

[英]How To Select Evaluated Value Of Expression<Func<T>> In Entity Framework Query

I'm creating a system to generate variable search queries in EF. 我正在创建一个在EF中生成变量搜索查询的系统。 To accomplish this I dynamically build up an Expression<Func<T>> like so. 为此,我像这样动态地构建了Expression<Func<T>>

Expression<Func<Entity, float>> matchScore = x => 0;
if (!string.IsNullOrWhiteSpace(NameLTB.Value))
{
    var words = NameLTB.Value.Split(' ').ToArray();
    var perWordValue = 2f / words.Length;
    foreach (var word in words)
        matchScore = ExpressionExt.Compose(matchScore, x => x.Name.Contains(word) ? perWordValue : 0f, Expression.Add);
}
//...

Then I order my query on this EF-compatible Expression<T> like so. 然后像这样在与EF兼容的Expression<T>上排序查询。

List<Entity> result;
using (var context = new DatabaseContext())
    result = context.Table.OrderByDescending(matchScore).Take(MaxResults).ToList();

The problem here is I don't know what the score was that caused the order to be the way it is. 这里的问题是我不知道导致订单按原样进行的得分是多少。 I'd love to be able to do this. 我很希望能够做到这一点。

List<Entity> result;
using (var context = new DatabaseContext())
    result = 
        (
            from x in context.Table
            let y = matchScore
            orderby y descending
            select new { Entity = x, MatchScore = y }
        )
        .ToList();

Of course the issue here is y is Expression<T> which isn't valid. 当然这里的问题是y is Expression<T> ,这是无效的。 I could use .Select(matchScore) but then don't have the original entity to go with it. 我可以使用.Select(matchScore)但是没有原始实体。

You can combine expressions with LINQKit like this: 您可以将表达式与LINQKit结合使用,如下所示:

Expression<Func<Entity, float>> matchScore = x => 0;
Expression<Func<Entity, float>> matchScoreInc;
string s = "a b";
if (!string.IsNullOrWhiteSpace(s))
{
    var words = s.Split(' ').ToArray();
    var perWordValue = 2f / words.Length;
    foreach (var word in words)
    {
        matchScoreInc = x => matchScore.Invoke(x) + (x.Name.Contains(word) ? perWordValue : 0f);
        matchScore = matchScoreInc.Expand();
    }
}

var q =
    from x in table.AsExpandable()
    let y = matchScore.Invoke(x)
    orderby y descending
    select new { Entity = x, MatchScore = y };

Note the use of Invoke , Expand and AsExpandable . 注意InvokeExpandAsExpandable Demo: 演示:

演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM