Take for example: a Person that has a collection of Pets. I want to only list the Persons that have at least 5 pets.
I have tried:
var result = (from a in UnitOfWork.CurrentSession.QueryOver<Person>()
where a.Pets.Count >4
select a
).List()
But it says it does not recognize the property Count (which makes sense because it is not a DB field). I also tried Count() and it still doesn't work saying it doesn't understand that function (throws exception).
I've tried all kinds of subqueries and criteria methods but I don't know enough to put it all together. And I don't know whether I shold use LINQ or HQL or QueryOver or Criteria...It would be much much mch easier in SQL but I don't want to "cheat"
I have been searching google like crazy, and everything I found either does not compile or I get a runtime error
You are using QueryOver instead of LINQ (Query<T>() extension method)
Related
I am sure this is easy (or that I am completely wrong), but all I want to do is get the single values against a LINQ query on a datatable and not use a for.. each loop to access them.
Scenario..
I have a datatable containing a number of rows. I run my query looking for a particular match on "EP" like such..
Dim qryB = From rw In oDT_Cables
Where rw("EP").Equals(br.Position)
Select ld = rw("LOAD"), tl = rw("TOT-LEN")
Now..
I know that I have only one result (due to checking upon insertion), so how do I simply access the items ld and tl without a for each loop??
I have tried:
qryb.elementat(1) error
qryb.elementat(ld) Not possible
qryb.tl not possible
Does anyone know how I can access tl and ld from the query please? It is much appreciated.
Brett
If you know for a fact that a LINQ query produces a single result then you call Single.
Dim result = qryB.Single()
If there may be no result but will never be more than one then you call SingleOrDefault and the result may be Nothing. If there will be at least one result but may be more and you want just the first, you call First. If there may be zero, one or more and you want the first if there is one then you call FirstOrDefault and the result may be Nothing.
Note that some LINQ providers don't support both options, e.g. LINQ to Entities (the LINQ provider for Entity Framework) supports First and FirstOrDefault but not Single or SingleOrDefault (unless it's changed recently) while, if I'm not mistaken, LINQ to SQL supports Single and SingleOrDefault but not First or FirstOrDefault.
Note that, if you were going to use ElementAt, you would have to specify 0 as the index. ElementAt works pretty much like indexing a array or other IList, so the first item is at index 0. You'd only use ElementAt for something in the middle of a query result though, given that you have Single, First and Last methods and their nullable equivalents.
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.
im pretty confused about lambdas and actually im not even sure i need them here
what im trying to do here is write a function that will return an object from a certain table with a certain criteria
so lets say i can write
function GetRecord(TableName as string,Criteria as string) as object
'do the linq-stuff
end function
now i dont care if the paremeters are strings or lambdas or whatever, but the end result must be that at runtime i dont know which table and which criteria will be used
as sometimes i need to get a customer record by email and sometimes a product by id etc.
if possible i would prefer returning a list of matching objects and then i would just use .firstordefault when i want 1 (such as by id...)
thank you , as always, for taking the time to read this and answer!
all the best
Have you considered using Dynamic LINQ?
Example:
Parsing an expression tree can be a challenging but rewarding method of solving this issue. I think it's overkill and I'd go with Dynamic Linq as decyclone mentioned.
A benefit of parsing the expression tree, however, is that you can have compile time checking of the submitted criteria.
Here are some articles that helped me.
How to: Implement an Expression Tree Visitor: http://msdn.microsoft.com/en-us/library/bb882521(VS.90).aspx
Building a custom IQueryable Provider: http://blogs.msdn.com/b/mattwar/archive/2008/11/18/linq-links.aspx
Walkthrough: Creating an IQueryable LINQ Provider: http://msdn.microsoft.com/en-us/library/bb546158(v=VS.90).aspx
Expression Tree Basics:
http://blogs.msdn.com/b/charlie/archive/2008/01/31/expression-tree-basics.aspx
I'm trying to reproduce the HqlQuery style 'select new ObjectToProjectOut' functionality. i.e. take a list of columns returned from a query and return as a list of ObjectToProjectOut types that are instantiated using a Constructor with as many parameters as the columns in the query.
This is in effect what 'select new ObjectToProjectOut' achieves in Hql.... but clearly that's not available in SqlQuery. I think I need to set a result transform and use either PassThroughResultTransformer, DistinctRootEntityResultTransformer etc to get it to work.
Anyone know what I should use ?
ok.... after looking at the NHibernate code it seems that I was looking for AliasToBeanConstructorResultTransformer.... of course!
However I may have found an nHibernate bug. If you have the same column name returned twice from two different tables (market.name and account.name, say) then by the time nHibernate returns the array from the db to the transformer, the first occurance of 'Name' will be used for both. Nasty.
Work around is to uniquely alias. With Hql, the sql generated is heavily aliased, so this is only a bug with SqlQuery.
Grrrr. Today must be my day, also found another nHibernate bug/issue I've posted to StackOverflow for comment.
You could use the AddEntity method to fill entities from a SQL query.
Here are two examples from the NHibernate docs:
sess.CreateSQLQuery("SELECT * FROM CATS")
.AddEntity(typeof(Cat));
sess.CreateSQLQuery("SELECT ID, NAME, BIRTHDATE FROM CATS")
.AddEntity(typeof(Cat));
I need to return a constant from an HQL query in NHIbernate
SELECT new NDI.SomeQueryItem(user, account, " + someNumber + ")
FROM NDI.SomeObject object
I am trying for something like above. I've tried this:
SELECT new NDI.SomeQueryItem(user, account, :someNumber)
FROM NDI.SomeObject object
And then later:
.SetParameter("someNumber", 1).List<SomeQueryItem>();
But in the first case I get a 'Undefined alias or unknown mapping 1'. Which makes some sense since it probably thinks the 1 is an alias.
For the second I get a 'Undefined alias or unknown mapping :someNumber' which again makes some sense if it never set the parameter.
I have to believe there's some way to do this.
Please feel free to continue to believe there is some way to do this - but with HQL there isn't!
Why would you want to anyway? If you want to update the value this property to the value you specify, then do so after you've loaded the objects. Alternatively, if your result set doesn't quite match to your objects, you could alway use a SQL query (which you can still do via an NHibernate session). But the purpose of NHibernate is to map what's in your database onto objects, so specifying a manual override like this is quite rightly not allowed.
It sounds like there is a (small?) disconnect between your domain objects and your database model. What about creating a small "DTO" object to bridge this gap?
Have your query return a list of SomeQueryItemDTO (or whatever you want to call it) which, due to the naming, you know is not a true part of your domain. Then have some function to process the list and build a list of true SomeQueryItem objects by incorporating the data that is extraneous to the database.
If you're already using the Repository Pattern, this should be easier since all the ugly details are hidden inside of your repository.