NHibernate: Return A Constant In HQL - nhibernate

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.

Related

IBM Maximo (Oracle SQL) Where Clause, defining a variable for reuse

I write many Maximo Where Clauses (which use Oracle SQL), and save them as public queries.
I encourage others to edit/customize the work I share with them.
But when my query uses the same string throughout it many times, it's tedious to make sure all instances are replaced. It's not like there's a built-in find-replace tool or anything.
Is there a way to define a custom string variable at the beginning, and reuse that variable many times thoughout the where clause?
No, you can't do that. But what you could do is make a relationship from your parent object to a system property / maxpropvalue child object where propname = 'company.app.varname. Then, you can use the System Properties app to change the value of the variable for all references. And you can make a reference to it in your query using standard :relationshiptomaxpropvalue.propvalue syntax.
HTH.

Updating SQL from object with groovy

When you read in a result set in Groovy it comes in a collection of maps.
Seems like you should be able to update values inside those maps and write them back out, but I can't find anything built into groovy to allow me to do so.
I'm considering writing a routine that allows me to write a modified map by iterating over the fields of one of the result objects, taking each key/value pair and using them to create the appropriate update statement, but it could be annoying so I was wondering if anyone else had done this or if it'sa vailable already in groovy.
It seems like just a few lines of code so I'd rather not bring in hibernate for this. I'm just thinking a little "update" method that would allow:
def rows=sql.rows(query)
rows[0].name="newName"
update(sql, rows[0])
to update the first guy's name in the database. Anyone seen/created such a monster, or is something like this already built into Groovy Sql and I'm just missing it?
(I suppose you may have to point out to the update method which field is the key field, but that's doable...)
Using the rows method will actually read out all of the values into a List of GroovyRowResult so it's not really possible to update the data without creating an update method like the one you mention.
It's not really possible to do that in the generic case because your query can contain joins or a column reference that is an aggregate, etc.
If you're selecting from a single table use the Sql.eachRow method however and set the ResultSet to be an updatable one, you can use the underlying ResultSet interface to update as you iterate through:
sql.resultSetConcurrency = ResultSet.CONCUR_UPDATABLE
sql.resultSetType = ResultSet.TYPE_FORWARD_ONLY
sql.eachRow(query) { row ->
row.updateString('name', 'newName')
row.updateRow()
}
Depending on the database/driver you use, you may not be able to create an updatable ResultSet.

Fluent NHibernate - HasMany mapping with condition

I have a HasMany mapping that needs a condition. I have this partially working, but there's got to be a better way than what I'm doing. The condition I'm using needs to look at a property on another table that I'm joining to. What I have so far is:
HasMany<MetaData>(x => x.MetaData).Table("MetaData")
.KeyColumn("DefinitionID")
.KeyColumn("TableID")
.Where("metadatade1_.SourceTable = 'Providers'")
.Cascade.SaveUpdate();
In the code above, the where clause is referencing "metadatade1_", because it's trying to fully qualify the name, and that is the name NH is generating. I've tried using "MetaDataDefinitions.SourceTable" (MetaDataDef... is the physical table name), and also just "SourceTable" by itself, however none of these worked.
Is there a way to not have it try and fully qualify the name on the condition and just pass "SourceTable='Providers'" OR is there a way I can have it reference the generated name without me having to manually plug it in?
In short, no. The Where method (and respectively the where= attribute in HBM.XML) accept only raw sql, and as such is prone to the problems you're seeing.
Your best option is to not use a collection and instead rely on a query to retrieve your metadata instances.

load record by predicate/lambda via vb.net linq

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

NHibernate - define where condition

In my application the user can defines search-conditions. He can choose a column, set an operator (equals, like, greater than, less or equal than, etc.) and give in the value. After the user clicks on a button and the application should do a search on the database with the condition. I use NHibernate and ask me now, what is the efficientest way to do this with NHibernate.
Should I create a query with it like (Column=Name, Operator=Like, Value=%John%)
var a = session.CreateCriteria<Customer>();
a.Add(Restrictions.Like("Name", "%John%"));
return a.List<Customer>();
Or should I do this with HQL:
var q = session.CreateQuery("from Customer where " + where);
return q.List<Customer >();
Or is there a more bether solution?
Thanks for your help.
Best Regards, Thomas
You can use either one of them. There might be hardly an differences between the two. But whatever you do make sure that your column names are in constants or are mapped to the column name otherwise your repository will be tightly coupled to your model definition i.e if you update the columnname you will have to go and update these statements yourself.
And when you are building the where clause makes ure you have a function that appends the right query. you will probably be having a switch case statement for the same.
In term of efficence there is no difference. In the HQL version I would prefer use a parameter instead of adding the where part as a string.
If you are using NH3.0 you can consider using QueryOver too, to avoid using string to describe your properties