代码之家  ›  专栏  ›  技术社区  ›  Bruno Reis

无法对IQueryable(nhibernate)执行.count()。

  •  2
  • Bruno Reis  · 技术社区  · 15 年前

    我有个恼人的问题。可能有点蠢,但我不知道。

    我在用 Linq到NHiberinate ,我想计算一个存储库中有多少项。下面是我的存储库的一个非常简单的定义,其中的代码很重要:

    public class Repository {
        private ISession session;
        /* ... */
        public virtual IQueryable<Product> GetAll() {
            return session.Linq<Product>();
        }
    }
    

    问题末尾的所有相关代码。

    然后,到 计数项目 在我的存储库中,我执行如下操作:

    var total = productRepository.GetAll().Count();
    

    问题是 total 是0。总是。但是,存储库中有项目。此外,我可以 .Get(id) 他们中的任何一个。

    我的 NHiBiNT日志 显示已执行以下查询:

    SELECT count(*) as y0_ FROM [Product] this_ WHERE not (1=1)
    

    这一定是“WhereNot(1=1)”条款造成这个问题的原因。

    我能做什么才能 .Count() 我的存储库中的项目?

    谢谢!

    编辑: 实际上repository.getall()代码有点不同…这可能会改变一些事情!它实际上是实体的通用存储库。一些实体还实现了iLogicalDeletable接口(它包含单个bool属性“isDeleted”)。在getall()方法中的“return”之前,我检查正在查询的实体是否实现了iLogicalDeletable。

    public interface IRepository<TEntity, TId> where TEntity : Entity<TEntity, TId> {
        IQueryable<TEntity> GetAll();
        ...
    }
    
    public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId>
        where TEntity : Entity<TEntity, TId>
    
    {
        public virtual IQueryable<TEntity> GetAll()
        {
            if (typeof (ILogicalDeletable).IsAssignableFrom(typeof (TEntity)))
            {
                return session.Linq<TEntity>()
                    .Where(x => (x as ILogicalDeletable).IsDeleted == false);
            }
            else
            {
                return session.Linq<TEntity>();
            }
        }
    }
    
    public interface ILogicalDeletable {
        bool IsDeleted {get; set;}
    }
    
    public Product : Entity<Product, int>, ILogicalDeletable
    { ... }
    
    public IProductRepository : IRepository<Product, int> {}
    public ProductRepository : Repository<Product, int>, IProductRepository {}
    

    编辑2 事实上 .GetAll() 总是返回实现iLogicaldDeletable接口的实体的空结果集(即,它总是添加 WHERE NOT (1=1) 条款。

    我认为Linq-to-NHibernate不喜欢打字。

    2 回复  |  直到 15 年前
        1
  •  1
  •   John Rayner    15 年前

    看起来这里有一个软删除模型,您正试图从getall()方法返回的数据中筛选出这些数据。我同意你的分析,nhibernate.linq没有正确处理类型转换,但你可能想用 query filter .

        2
  •  0
  •   Kim Johansson    15 年前
    public virtual IQueryable<TEntity> GetAll()
    {
      if (typeof(ILogicalDeletable).IsAssignableFrom(typeof(TEntity)))
      {
        return session.Linq<TEntity>().OfType<ILogicalDeletable>()
          .Where(x => !x.IsDeleted).Cast<TEntity>();
      }
    
      return session.Linq<TEntity>();
    }
    

    试试看。

    推荐文章