繁体   English   中英

Linq2db:按嵌套属性字段过滤

[英]Linq2db: filter by nested property field

我在我的项目中使用了 linq2db ORM,我有以下查询:

var query =
        from t in _db.Transactions
        from a in _db.Accounts.LeftJoin(a => a.Id == t.AccountId)
        from u in _db.Users.LeftJoin(u => u.Id == a.UserId)
        select Transaction.Build(t, u, a);

和 Build 方法如下所示:

public static Transaction Build(Transaction transaction, User user, Account account)
{
  account.User = user;
  transaction.Account = account;
  return transaction;
}

Users 表包含 FullName 列,我想知道是否可以按用户的全名过滤交易?

if (!string.IsNullOrWhiteSpace(userNameFilter))
{
  query = query.Where(t => t.Account.User.FullName.Contains(userNameFilter));
}

是否可以使用 linq2db 实现它?

在工厂方法调用Transaction.Build(t, u, a) ,linq2db 丢失了有关字段映射和查询的信息,仅适用于物化而不适用于过滤。 这适用于任何当前可用的 LINQ 提供程序。

你可以用 linq2db 做什么来使代码可重用 - 使用ExpressionMethodAttribute重写你的函数Transaction.Build

static Func<Transaction, User, Account, Transaction> _buildFunc;

static Expression<Func<Transaction, User, Account, Transaction>> BuildImpl()
{
   return (Transaction transaction, User user, Account account) => 
      new Transaction
      {
         Id = transaction.Id,
         ... // copy all needed fields

         Account = new Account 
         {
            Id = account.Id,
            ... // copy all needed fields

            User = user
         }
      }
   );
}

[ExpressionMethod(nameof(BuildImpl))]
public static Transaction Build(Transaction transaction, User user, Account account)
{
   // we left function usable even for non-query scenarios.
   _buildFunc ??= BuildImpl().Compile();
   return _buildFunc(transaction, user, account);
}

在这些操作之后,您的查询可以在Transaction.Build调用之后进行过滤。

在后台,linq2db 会找到ExpressionMethodAttribute声明并用BuildImpl函数中定义的 Expression 替换Transaction.Build调用。 在分析 LINQ 查询之前示意性地将其转换为以下变体:

var query =
    from t in _db.Transactions
    from a in _db.Accounts.LeftJoin(a => a.Id == t.AccountId)
    from u in _db.Users.LeftJoin(u => u.Id == a.UserId)
    select new Transaction
    {
        Id = t.Id,
        ... // copy all needed fields

        Account = new Account 
        {
            Id = a.Id,
            ... // copy all needed fields

            User = u
        }
    };

暂无
暂无

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

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