Can't .Count () for IQueryable (NHibernate)

I'm having an annoying problem. It might be something silly, but I couldn't find out.

I am using Linq to NHibernate and I would like to count the number of items in a repository. Here's a very simplified definition of my repository with the code that matters:

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

      

cases> All relevant codes at the end of the question.

Then, to count the items in my repository, I do something like:

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

      

The problem is that it total

is 0. Always. However, there are items in the repository. Also, I can do .Get(id)

any of them.

My NHibernate log shows that the following query was executed:

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

      

It should be that "WHERE not (1 = 1)" indicates the cause of this problem.

What can I do to be able to have .Count()

items in my repository?

Thank!

EDIT: Actually the repository.GetAll () code is slightly different ... and that might change something! This is actually a shared repository for Entities. Some of the objects also implement the ILogicalDeletable interface (it contains one bool "IsDeleted"). Just before "returning" inside the GetAll () method, I check to see if the request implements an Entity that implements 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 {}

      

Edit 2 : actually .GetAll()

always returns an empty result set for objects that implement the ILogicalDeletable interface (i.e. it ALWAYS adds a clause WHERE NOT (1=1)

.

I think Linq for NHibernate doesn't like typecasting.

+2


source to share


2 answers


It looks like you have a soft delete model here, and you are trying to filter them out from the one returned by the GetAll () method. I agree with your analysis that NHibernate.Linq does not handle the type correctly, but you can try replacing it with a query filter .



+1


source


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

      



Try it.

0


source







All Articles