【问题标题】:Entity Framework - LINQ - Use Expressions in Select实体框架 - LINQ - 在选择中使用表达式
【发布时间】:2018-01-10 17:20:10
【问题描述】:

我在我的代码中使用了一些 EF LINQ 表达式来将我的模型的复杂查询保存在一个地方:

public static IQueryable<User> ToCheck(this IQueryable<User> queryable, int age, bool valueToCheck = true)
{
    return queryable.Where(ToBeReviewed(age, valueToCheck));
}

public static Expression<Func<User, bool>> ToCheck(int age, bool valueToCheck = true)
{
    return au => au.Status == UserStatus.Inactive
        || au.Status == UserStatus.Active &&
        au.Age.HasValue && au.Age.Value > age;
}

然后我可以在查询中使用它们:

var globalQuery = db.Users.ToCheck(value);

还有在选择中:

var func = EntityExtensions.ToCheck(value);

var q = db.Department.Select(d => new
{
    OrdersTotal = d.Orders.Sum(o => o.Price),
    ToCheck = d.Users.AsQueryable().Count(func),
})

我想要实现的是实际使用相同的表达式/函数在一个选择中,为每一行评估它。

var usersQuery = query.Select(au => new {
    Id = au.Id,
    Email = au.Email,
    Status = au.Status.ToString(),
    ToBeChecked = ???, // USE FUNCTION HERE
    CreationTime = au.CreationTime,
    LastLoginTime = au.LastLoginTime,
});

我很高兴这将是一种使用普通 EF 功能或 LINQKit 的方法,但找不到它。

【问题讨论】:

  • 你能解释一下db.Department.Select(d =&gt; new { OrdersTotal = d.Orders.Sum(o =&gt; o.Price), ToCheck = d.Users.AsQueryable().Count(func), })和你想要什么之间的区别吗?
  • 第一个示例用作查询集合的函数,最后一个示例是我想在特定行上重用我的函数以获取其值的地方
  • 你能添加你想要调用的示例函数吗?
  • 示例函数是最后一个,之前的调用用于过滤或计数实体。最后一个是查询和检索每一行的值本身
  • 看看AsExpandableInvoke 自定义扩展方法。像query.AsExpandable().Select(.... ToBeChecked = func.Invoke(au)) 这样的东西。另一个例子 - stackoverflow.com/questions/38398507/…

标签: entity-framework linq linqkit


【解决方案1】:

回答我自己的问题:)

正如@ivan-stoev 所指出的,使用Linqkit 是解决方案:

var globalQueryfilter = db.Users.AsExpandable.Where(au => au.Department == "hq");

var func = EntityExtensions.ToCheck(value);
var usersQuery = globalQueryfilter.Select(au => new
{
    Id = au.Id,
    Email = au.Email,
    Status = au.Status.ToString(),
    ToBeChecked = func.Invoke(au),
    CreationTime = au.CreationTime,
    LastLoginTime = au.LastLoginTime,
});
return appUsersQuery;

需要使用 Linqkit 中的 AsExpandable 扩展方法以及带有 select 方法中的函数的 Invoke

【讨论】:

    【解决方案2】:

    我想再补充一个例子:

    Expression<Func<AddressObject, string, string>> selectExpr = (n, a) => n == null ? "[no address]" : n.OFFNAME + a;
    
    var result = context.AddressObjects.AsExpandable().Select(addressObject => selectExpr.Invoke(addressObject, "1"));
    

    此外,帮助器中的表达式可以是静态的。 p.s.请不要忘记添加“使用 LinqKit;”并使用“AsExpandable”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-20
      • 2010-10-29
      • 1970-01-01
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多