不能.Count()在IQueryable(NHibernate)上

时间:2009-09-07 13:59:53

标签: linq nhibernate count

我有一个恼人的问题。这可能是愚蠢的,但我找不到。

我正在使用 Linq到NHibernate ,我想计算一下存储库中有多少项。这是我的存储库的一个非常简化的定义,代码很重要:

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

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

然后,要在我的存储库中计算项目,我会执行以下操作:

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

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

我的 NHibernate日志显示执行了以下查询:

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

必须是“WHERE not(1 = 1)”条款导致此问题。

如果能够.Count()我的存储库中的项目,我该怎么办?

谢谢!

编辑:实际上,repository.GetAll()代码有点不同......这可能会改变一些东西!它实际上是实体的通用存储库。一些实体也实现了ILogicalDeletable接口(它包含一个bool属性“IsDeleted”)。就在GetAll()方法内部的“返回”之前,我检查我查询的实体是否实现了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()总是为实现ILogicalDeletable接口的实体返回一个空结果集(即,它总是添加一个WHERE NOT (1=1)子句。 / p>

我认为Linq对NHibernate不喜欢类型转换。

2 个答案:

答案 0 :(得分:1)

看起来你在这里有一个软删除模型,并且你试图通过GetAll()方法返回这些模型。我同意您的分析,NHibernate.Linq没有正确处理类型转换,但您可能想尝试用query filter替换它。

答案 1 :(得分:0)

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>();
}

试试。