nHibernate QueryOver Projects - are Select and Where the same thing? - nhibernate

Using nHibernate QueryOver, if I want to enforce a projection for performance, are "Select" and "Where" the same thing? In other words, will ..
var member = session.QueryOver<Member>()
.Select( projections => projections.Email == model.Email )
.Take(1).SingleOrDefault();
Run the same as
var member = session.QueryOver<Member>()
.Where( context => context.Email == model.Email )
.Take(1).SingleOrDefault();
Or is there a difference in the two?

Select projects (you could also say maps); Where filters. This is the same as SQL and all LINQ providers (and QueryOver is also sort of a LINQ provider). It seems that in this case you want to filter, not project, so you need Where

No offense intended, but I think the best way to answer a question like the one you asked is to try it. Sometimes things become clearer when you can see the output.
That said, when you use Select, you're telling NHibernate how to project your data. This determines the final makeup of the data resulting from the query. There's a little bit more to this, but that's the general idea. You use Where when you want to specify the criteria that the data that you are querying should satisfy.

Related

IQueryable Extension to Generate Temporal Table "AS OF" Queries

Having failed to find a satisfying solution, let me post this here:
We're using NHibernate as our ORM and are just beginning to use Sql Server temporal tables. We therefore need some kind of extension to IQueryable (or the HQL Builder or an InterceptingProvider or something) that will allow us to add the "AS OF" clause to our queries, something like
var results = session.Query<Company>
.Where(c => c.Name == "FogCreek")
.AsOf(DateTime.Today.AddYears(-1));
I've been struggling with it too and gave up as I lost too much time trying to find better approach...
So far I've injected FOR SYSTEM_TIME AS OF into SQL using custom HqlGeneratorForMethod but this gave me invalid SQL expression. So I had to fix it in OnPrepareStatement. This is hacky and not elegant solution but works for most simple cases.
Please look at my solution here and feel free to reply if you find better solution

NHibernate: How to select the root entity in a projection

Ayende describes a really great way to get page count, and a specific page of data in a single query here:
http://ayende.com/blog/2334/paged-data-count-with-nhibernate-the-really-easy-way
His method looks like:
IList list = session.CreateQuery("select b, rowcount() from Blog b")
.SetFirstResult(5)
.SetMaxResults(10)
.List();
The only problem is this example is in HQL, and I need to do the same thing in an ICriteria query. To achieve the equivalent with ICriteria, I need to do something like:
IList list = session.CreateCriteria<Blog>()
.SetFirstResult(5)
.SetMaxResults(10)
.SetProjection(Projections.RootEntity(), Projections.SqlFunction("rowcount", NHibernateUtil.Int64))
.List();
The problem is there is no such thing as Projections.RootEntity(). Is there any way to select the root entity as one of the projections in a projection list?
Yes, I know I could just use CriteriaTransform.TransformToRowCount() but that would require executing the query twice - once for the results and once for the row count. Using Futures may help a little by reducing it to one round-trip, but it's still executing the query twice on the SQL Server. For intensive queries this is unacceptable. I want to avoid the overhead, and return the row count and the results in the same query.
The basic question is: using ICriteria, is there any way to select the root entity AND some other projection at the same time?
EDIT: some related links:
https://nhibernate.jira.com/browse/NH-1372?jql=text%20~%20%22entity%20projection%22
https://nhibernate.jira.com/browse/NH-928
I implemented a RootEntityProjection. You can try the code, which you can find at: http://weblogs.asp.net/ricardoperes/archive/2014/03/06/custom-nhibernate-criteria-projections.aspx.
Let me know if it helped.

Late evaluation with NHibernate QueryOver

NHibernate.Linq returns IQueryable giving me late evaluation. Can this also be done with QueryOver?
Update:
I will use it to define lots of queries where only a subset would be used. Therefor Future is not the solution, which would execute them all.
I like the IQueryable (IEnumerable) return type from NHibernate.Linq, that will never execute the query if never used.
Firstly, even QueryOver is just a set of definitions to be later converted to the SQL statement. So until you are working with a reference to a
IQueryOver<Entity, Entity> ab = session.QueryOver<Entity>();
and not calling List<Entity>() ... the execution is deferred. That's also how you can use the Detached queries 16.1. Structure of a Query
QueryOver<Cat> query = QueryOver.Of<Cat>()
.Where(c => c.Name == "Paddy");
Another powerful feature is Future. This represents a very easy way how to put few queries on the stack, and only when first of them is required... all are executed and passed to DB Server as a batch. Read here more: NHibernate Futures
They essentially function as a way to defer query execution to a later
date, at which point NHibernate will have more information about what
the application is supposed to do, and optimize for it accordingly
The biggest difference is that it cannot be returned as IQueryable when using QueryOver
EDIT: Extend on a question update
While IQueryable<TEntiy> could be returned only from a session.Query<TEntity>() and not when using QueryOver, ICriteria, HQL ... the same behavior could not be reached when using QueryOver.

How do you go about writing "dynamic sql" filters using querystring values in ASP.NET MVC?

I just can't seem to wrap my mind around this concept... I want to allow users to apply a number of "filters" to a dataset (preferably in the querystring to allow bookmarking the filtered results), retrieved using Rob Conery's Massive dynamic data access "tool".
I could simply write a whole bunch of if's, then write a direct query by each "rule" I catch... but that seems to defeat the purpose of "dynamic sql".
Is there a general pattern/best practice for this in C#/ASP.NET MVC?
I think the concept is a bit broad to say there's a pattern/best practice for doing something like this. That said, I think using something like LINQ to SQL or Entity Framework would make a good dynamic query engine because you can do stuff like this:
var query = DBContext.Items.Select(x => x.Name);
switch(QueryString["Type"])
{
case "Dog":
query = query.Where(x => x.Type == "Dog";
break;
case "Cat":
query = query.Where(x => x.Type == "Cat";
etc....
}
query = query.Where(x => x.Owner.Name == QueryString["Owner"]);
ResultsDataGrid.Datasource = query;
Obviously some psuedo-code there, but the good thing about LINQ to SQL in this case is the deferred execution. query doesn't get run until the databinding, and includes whatever filters you add dynamically. It also gives you type-safety and will prevent SQL Injection. You can do something similar by actually building up the SQL query that will be run at the end, but it's going to be error-prone and require a lot of checks and balances.

Is there a way to combine results from two IQueryable<T> using NHibernate & Linq?

I have two separate queries that both return the same IQueryable, and I'd like to combine them prior to projection. It looks like neither Union or Concat are implemented in Linq to NHibernate? Does anyone know how I might go about achieving this?
It's not possible. You'll have to do it on the client.
Example:
var allItems = queryable1.AsEnumerable().Concat(queryable2)
#Diago Mijelshon gives a good answer, but I would like to add that depending on what you're doing with the data, you may need to first cast it to an array or list so that NHibernate doesn't try to do any funny stuff with your operations.
I've used Entity Framework for years and I'm well familiar with this, and I've only used NHibernate a little bit, but the two tools appear to be similar in this regard.