5

I'am using wrapper to get some data from table User

IQueryable<StarGuestWrapper> WhereQuery =    
session.Linq<User>().Where(u => u.HomeClub.Id == clubId && u.IsActive).Select(
                    u =>
                    new StarGuestWrapper()
                        {
                            FullName = u.Name + " " + u.LastName,
                            LoginTime = u.SomeDateTime,
                            MonthsAsMember = u.SomeIntergerValue,
                            StarRating = u.SomeOtherInteregValue, 
                            UserPicture = u.Photo.PhotoData, 
                            InstructorFullName = u.SomeInstructorName,
                            TalkInteractionDuringSession = u.SomeBoolValue,
                            GoalInteractionDuringSession = u.SomeOtherBoolValue
                        });

I use this without a problem as a IQueryable so I can do useful things before actually running the query. Like :

WhereQuery.Skip(startRowIndex).Take(maximumRows).ToList();

and so on.

The problem occurs using 'where' statement on query. For example:

WhereQuery.Where(s => s.StarRating == 1)

will throw an exception in runtime that 'StarRating' doesn't exist in User table - of course it doesn't it's a wrappers property. It will work if I materialize query by

WhereQuery.AsEnumerable().Where(s => s.StarRating == 1)

but then it loses all the sens of using IQueryable and I don't want to do this.

What is strange and interesting that not all properties from wrapper throw error, all the bool values can be used in where statement. Example :

WhereQuery.Where(s => s.TalkInteractionDuringSession)

It works in EntityFramework , why do I get this error in NHibernate and how to get it working the way I want it to ?

Jacob
  • 914
  • 2
  • 10
  • 30
  • How do you intend to query (which uses the data store) on something that isn't in the data store? The only way to find all those with StarRating=1 is to enumerate over everything. – Lasse V. Karlsen Apr 12 '10 at 12:08
  • @Lasse you seem not to understand how ORM's work, it's a query not a collection, it doesn't contain data it queries database for this data. Don't mind the hardcoded values in this wrapper, it's only an exaple , I shold write u.SomeValue instead. – Jacob Apr 12 '10 at 12:14
  • It *was* a query before you created a new result type, at that point you break the connection back to the data store, the result of your select statement is no longer a queryable you can continue to add .Where clauses to. This is the same as this type of code: SELECT * FROM (magic C# code here from (SELECT * FROM yourtable)) – Lasse V. Karlsen Apr 12 '10 at 12:58
  • 2
    @Lasse, then why do the boolean fields work? – Marcelo Cantos Apr 12 '10 at 13:03
  • Good question, turns out I don't know how this works after all then. – Lasse V. Karlsen Apr 12 '10 at 13:05
  • 5
    I'm pretty sure it's a bug in nhibernate linq provider. – Egor Pavlikhin Apr 13 '10 at 04:35
  • @HeaveyWave - Ayende's one doesn't do complex queries or projections very well. – kͩeͣmͮpͥ ͩ Apr 14 '10 at 16:07

1 Answers1

2

Keep in mind the older nHibernate Linq provider is only a partial implementation and is no longer being actively worked on. A new and more complete linq provider is being developed now and will be part of NH3.0 (you can checkout the trunk and build it to see if it addresses this problem).

My recommendation is to change your code to call ToList() at the point when you explicitly wish to hit the database. You are passing a future valued query back from your repository at which point anything could technically happen to the query. Even EF and LINQ2SQL cannot translate any possible linq query into SQL.

I do realize this isn't what you want to be able to do, but I think you are trying to bend the framework to do something in a way this isn't very natural at all.

Chris Nicola
  • 14,384
  • 6
  • 47
  • 61