为子查询提供表达式

时间:2011-08-06 16:26:50

标签: .net entity-framework linq-to-entities

我有以下LINQ To Entities查询(简化形式):

ctx.BattlesUsers.Where(bu => bu.DateTime == ctx.BattlesUsers.
   Where(BattleUserSpecifications.BattleIdIsEqualTo(bu.BattleId)).
   Max(bu1 => bu1.DateTime));

抛出异常“内部.NET Framework数据提供程序错误1025。”。

这里的问题是我的规范电话。此问题的常见解决方案是将规范表达式调用移出查询并将表达式直接传递给Where。但它不会在这里工作,因为我需要将bu.BattleId传递给表达式。

更新

以下是BattleIdIsEqualTo的代码:

public static Expression<Func<Model.Entities.BattleUser, bool>> UserIdIsEqualTo(long userId)
{
   return bu => bu.UserId == userId;
}

3 个答案:

答案 0 :(得分:3)

如果我认为BattleUserSpecifications.BattleIdIsEqualTo(int battleId)看起来与return bu => bu.BattleId == battleId;类似,那么我将使用新规范进行以下操作:

public static class BattleUserSpecifications
{
    public static Expression<Func<BattleUser, bool>> FilterByDateTime(
        IQueryable<BattleUser> battleUsers)
    {
        return bu => bu.DateTime == battleUsers
            .Where(bu1 => bu1.BattleId == bu.BattleId)
            .Max(bu2 => bu2.DateTime);
    }
    //...
}

然后以下查询有效:

var query = ctx.BattlesUsers.Where(
    BattleUserSpecifications.FilterByDateTime(ctx.BattlesUsers));

这可能不是你想要的,只是一种解决方法。我可以使用原始查询重现您的异常。 “内部错误”看起来代码在内部遍历一条相当意外的路径,而且很可能只有MS / EF团队才能真正回答出错的地方。您可能需要重写查询以获得所需的结果。

答案 1 :(得分:1)

我要再给另一个刺。如果您的目标是为每个战斗人员获取最新的战斗用户,那么您可以使用此查询

    ctx.BattlesUsers.GroupBy(bu => bu.BattleId)
    .Select(bug => bug.OrderByDescending( bu => bu.DateTime).FirstOrDefault())

如果您想在此时使用表达式函数对其进行过滤,但是您需要从外部获取用户ID,然后通过Where子句将其传递到最后。

答案 2 :(得分:0)