【问题标题】:What is the best way to dynamically add to a where clause in a nhibernate query in C#?在 C# 的休眠查询中动态添加到 where 子句的最佳方法是什么?
【发布时间】:2014-04-08 17:58:03
【问题描述】:

我有一段 C# 代码使用 nhibernate 查询数据库,如下所示:

      public void Query()
      {

        IEnumerable<Project> list = session.Query<Project>()
            .Where(p => !p.IsDeleted)
            .FetchMany(r => r.UnfilteredProjectApplications)
            .ThenFetch(r => r.Application)
            .ToList()
      }

我现在有许多用户驱动程序过滤器,因此,根据传入的参数,我想添加到 where 子句。所以是这样的:

       public void Query(string name)
      {

         if (!String.IsNullOrEmpty(name)
          {
            IEnumerable<Project> list = session.Query<Project>()
             .Where(p => !p.IsDeleted && p.Name == name)
            .FetchMany(r => r.UnfilteredProjectApplications)
            .ThenFetch(r => r.Application)
            .ToList()
          }
      }
      else
      {
        IEnumerable<Project> list = session.Query<Project>()
            .Where(p => !p.IsDeleted)
            .FetchMany(r => r.UnfilteredProjectApplications)
            .ThenFetch(r => r.Application)
            .ToList()
      }

用户可以选择一个或多个过滤器。可以想象,考虑到大量的组合,上面的代码会变得异常复杂。有没有一种优雅的方法可以在这里附加一个带有额外逻辑块的 where 子句。有些可能很简单,例如

         p.Name == name

但其他可能更复杂,例如:

         p.ProjectApplications.Select(r => r.Application).Any(s => applicationIds.Contains(s.Id)))

正如我所说,可能有零个或多个不同的过滤器。 .

更新:

我在其他情况下看到,人们建议像

这样构建 where 子句
query = query.where (r=>r.name = "XYZ");
query = query.where (r=>r.Age > 10);
query = query.where (r=>r.Gender = "Male");

但这似乎不适用于 nhibernate,所以一开始是一个通用的 lambda 问题,现在是 nhibernate 的一个特定问题

【问题讨论】:

  • @Servy - 事实证明我的问题现在是特定于 nhibernate 的,因为重复项中的建议不适用于 nhibernate linq。如果这样更容易,我可以删除问题并重命名
  • 您永远不应该只说“不起作用”。如果你写得正确,我会惊讶地发现它不起作用,它几乎肯定会起作用。无论如何,重要的是要详细解释为什么它不起作用,以及究竟发生了什么不应该。我无法理解为什么多次调用Where 会失败。更有可能的是,您只是将对象投射到某些时候不应该的东西。
  • NHibernate 的 LINQ 提供程序在我的经验中非常有问题。您可以使用 QueryOver 作为替代的强类型 API 来使用 NHibernate 进行查询。使用 QueryOver,可以很容易地动态构建 where 子句、选择列表等。

标签: c# nhibernate filter lambda where-clause


【解决方案1】:

您可以使用PredicateBuilder&lt;T&gt; 创建表达式并将其应用于您的查询,例如:

public void Query(string name)
{
    Expression<Func<Project, bool>> filter = PredicateBuilder.True<Project>();

    filter = filter.And(p => !p.IsDeleted);

    if (!string.IsNullOrEmpty(name)
        filter = filter.And(p => p.Name == name);

    IEnumerable<Project> list = session.Query<Project>()
                                        .Where(filter)
                                        .FetchMany(r => r.UnfilteredProjectApplications)
                                        .ThenFetch(r => r.Application)
                                        .ToList();
}

使用 PredicateBuilder,您可以创建所需的表达式,使用 And()Or()Not() 方法添加条件。

【讨论】:

    【解决方案2】:

    如果你看起来像这样:

    public IList<Bestellung> GetAll(Expression<Func<Order, bool>> restriction)
    {
        ISession session = SessionService.GetSession();
        IList<Order> bestellungen = session.Query<Order>()
                        .Where(restriction).ToList();
        return bestellungen;
    }
    

    阅读this

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 2016-03-19
      • 2015-12-20
      • 1970-01-01
      相关资源
      最近更新 更多