用ServiceStack为OrmLite构建表达式

本文关键字:构建 表达式 OrmLite ServiceStack | 更新日期: 2023-09-27 18:12:50

我试图使用.And()建立一个表达式并传递给db.Select<>()。抛出的错误是:

类型为Proj1的变量'q'。玩家"从范围引用",但是没有定义

下面的代码:

Expression<Func<Player, bool>> exp = (q => q.ClientId == request.ClientId);
if (request.IsWinner.HasValue)
    if (request.IsWinner.Value)
    {
        if (game != null)
            exp = exp.And(q => q.WinHistory.Any(y => y.GameId == game.Id));
        else
            exp = exp.And(x => x.WinHistory.Any());
    }
    else
    {
        exp = exp.And(x => x.WinHistory.IsEmpty());
    }

var players = Db.Select<Player>(exp);

基表达式工作正常。然而,当它与.And()组合时,它抛出错误。

我用错了吗?

用ServiceStack为OrmLite构建表达式

您不能通过查询集合来执行JOIN查询,您需要显式地指定您想要的JOIN查询,例如:

if (request.Winner == true)
{
    q.Join<WinHistory>(); //uses implicit reference convention
    if (game != null)
        q.And<WinHistory>(w => w.GameId = game.Id);
}
else
{
    q.LeftJoin<WinHistory>()
     .And<WinHistory>(w => w.Id == null);
}
var players = db.Select(q);

上面的代码使用了OrmLite的隐式引用约定,因此如果可以推断连接关系,则不需要指定连接关系。您可以通过自己指定显式连接来覆盖此行为。

查询blobbing Complex Type

由于SQL不允许查询文本blobs,如果WinHistory集合是一个blobs复杂类型,那么你只能使用Linq2Objects(即从DB返回后)在客户端过滤集合,例如:

var players = db.Select<Player>(q => q.ClientId == request.ClientId);
if (request.IsWinner != null)
{
    players = request.IsWinner.Value
      ? players.Where(x => x.WinHistory.Any(y => y.GameId == game.Id)).ToList()
      : players.Where(x => x.WinHistory.Any().ToList()
}
else
{
    players = players.Where(x => x.WinHistory.IsEmpty());
}