I have a question on linq to nhibernate. I need to create a query in which I could use string comparison:
session.Linq<User>()
.Where(u => String.Compare(u.Name, givenName) < 0)
.ToList()
Do I understand correctly that this is not supported in linq-to-nhibernate? Is there a way to use string comparison in linq-to-nhibernate?
The new integrated provider in NHibernate 3 allows extending it to support pretty much any construct you want.
Check http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-extension.html for a full example.
Of course, you'll need to think of a reasonable HQL representation of that expression.
This is no longer needed. The lambda expression in the question is now supported.
Related
any one know what kind of query is this??
var r = dc.user_details.Where(a => a.username.Equals(u.username) && a.passkey.Equals(u.passkey)).FirstOrDefault();
It is LINQ query. (The Enumerable methods are part of system.linq namespace)
The method "where" is part of "Enumerable Methods".
https://msdn.microsoft.com/en-us/library/system.linq.enumerable_methods(v=vs.110).aspx
Inside "Where" the predicate is a lamda expression. (This is a C# programming concept. Not part of LINQ)
https://msdn.microsoft.com/en-us/library/bb397687.aspx
Again the "FirstOrDefault" is a "Enumerable method", You can find it in the first link.
These are an extension methods that achieves the same as LINQ. It is another way for writing LINQ queries.
This is a linq query which checks the username and passkey and gives the result weather the user name and passkey exist in the table or not.
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.
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.
How to make LINQ case sensitive and NOT case sensitive depending on the situation?
I'm using sql server 2008 and Entity Framework 4.0.
I changed the COLLATION to make SQL Server case sensitive. so that for scenarios like these:
query = query.Where(x => x.Username == username);
it works great.
However I need to be able to pull out data from db ignoring case when searching by subject (or name or similar) like so:
query = query.Where(x => (x.Name.Contains(Name)));
which doesn't work when record is "TestString" and i'm looking for "test" or "Test" or similar. How would i make it so that when it would find a text or part of a string in a text?
thanks
LINQ has no concept of case sensitivity, it only cares about boolean evaluation. So if you want to ignore case, you should do something like:
query = query.Where(x => (x.Name.ToLower().Contains(Name.ToLower())));
Chances are you will want to pass a CultureInfo to ToLower() (or use ToLowerInvariant()), and you might want to cache the result of Name.ToLower() so as to not have to perform that operation a potentially large number of times, but this should get you started.
query = query.Where(x => string.Equals(x.Name, Name, StringComparison.CurrentCultureIgnoreCase));
Read my reply to this:
String.Equals() not working as intended
It isn't the reply you wanted, probably :-)
Ah... and if you have to convert to the same case to make comparisons, ToUpper is better than ToLower. Don't ask me why. But you can read here: Case insensitive string compare in LINQ-to-SQL
Queryable.Contains has an overload taking an IEqualityComparer<T> used for comparision. See msdn. If you supply a case insensitive comparer, this should work - I'm quite sure there is one in the framework already.
I'm making a search with NHibernate 3.0 IQueryOver, where I have a keyword for a search. I need to search in a string to see if it is part of the string,
Query().Where(e => e.Name.Contains(keyword)).List();
But this does not do the job as expected. How should such a search be performed?
I checked the NHibernate source and the ExpressionProcessor for the QueryOver string like you posted above does not support Contains. The operations it supports are IsLike and IsIn. You could either use IsLike or if you are keen on Contains, use Linq. For example :
(from user in db.Users
where names.Contains(user.Name)
select user);
or
query.Where(person.Name.IsLike("%test%")) //In QueryOver
I am guessing that you got an "Unrecognised method call" exception.
As far as I know (at least, for SQL Server, it doesn't seem to work with SQL Server Compact), NHibernate translates that IQueryable into a case insensitive "like '%keywork%'" where clause. Did you expect a case sensitive search?