Nhibernate throws Object of type 'System.Linq.

2019-02-18 20:54发布

问题:

using nhibernate as ORM
Trying to get one entity

   var users = GetUsersData(repository);
   return users.Where(f => f.Id == id).FirstOrDefault();//there is an exception

exception:

Object of type 'System.Linq.EnumerableQuery1[Entity]' cannot be converted to type 'System.Linq.IQueryable1[System.Object[]]'.

but when i do it that way:

var users = GetUsersData(repository);
return users.Where(f => f.Id == id).ToArray().FirstOrDefault();

it runs fine. Point me, what's wrong?

in GetUsersData i do :

private static IQueryable<User> GetUsersData(IUserRepository repository)
        {
            return repo.GetAll().Select(user => new User
                {
                    Id = user.Id,
                    Phones = user.Phones.Select(s => new Phone() { Number = s.Number }),
                    ...
                }).AsQueryable(); 

回答1:

.AsQueryable() will wrap the given IQueryable from NH needlessly into a new Queryable but since NH will by default use object arrays as results and transform it later it will fail casting.

Also Selecting the user into another User will prevent changetracking and is needless copying.

repo.GetAll().Where(f => f.Id == id).FirstOrDefault(); should be enough

or even better because of the sessioncache usage

var user = session.Get<User>(id);
if (user == null)
    // user with given Id does not exist