Fluent NHibernate RegisterFunction SQLFunctionTemplate usage - nhibernate

I've seen this opportunity reported at least half a dozen times with about as many responses.
My problem is, I've got a MySQL database function defined, we'll call it "my_func(int val) returns int", which works fine if I test directly on the database.
I've also gotten it to work with a direct SQL passthrough my repository implementation, which is okay, but I'd rather route it through Hql, for some god-awful reason...
So... I've got a MySQL5Dialect setup to register the function and I'm having some difficulty parsing through the expected conventions.
My understanding is that I need to prefix the function name with "dbo." at some point during the function registration?
Something like this,
//...
RegisterFunction("my_func", new SQLFunctionTemplate(NHibernateUtil.Int32, "my_func(?1)"));
//...
And then through my repository,
var value = repository.FindByHQL<int>("select my_func(2)").Single();
Where FindByHQL returns an IList.
Any thoughts why this wouldn't work.
I'm running the latest WAMP (2.1e I think).
Enough info? Let me know if I can provide any further details.
Thanks,
Michael

select my_func(2)
is not valid HQL, regardless of whether the function is registered or not.
You can use SQL instead if that's your use case.
Post full exception with stack trace if it's not and this was just a simplified example.

Related

Unresolved reference: addCriteria (Kotlin)

I am trying to write some basic MongoDB custom queries in Kotlin.
I've seen nearly everywhere that people use a method addCriteria:
val query: Query = Query()
query.addCriteria(Criteria.where("field1").exists(true)))
But it seems there is no method addCriteria in Query which I use: org.springframework.data.mongodb.repository.Query
I am very confused. Cannot find any explanations on how to write custom MongoDB queries in Kotlin with Spring Data except using this method.
So, I was very close to the problem's solution. I really used wrong Query, despite it's path looks really logical. I needed this one: org.springframework.data.mongodb.core.query.Query.
I used org.springframework.data.mongodb.repository.Query, which is Query annotation, not the class

How to prevent empty list errors in in clause in sql?

One common problem we have in our codebase is that people forget to check if a list is empty before using it in an in clause.
For example (in Scala with Anorm):
def exists(element: String, list: List[String]): Boolean =
SQL("select {element} in {list} as result")
.on('element -> element, 'list -> list)
.as(SqlParser.bool("result").single)
This code works perfectly well as long as list has at least one element.
If it has 0 elements, you get a syntax error, which is weird if you're used to other programming languages that would allow this empty list case.
So, my question is: what's the best way to prevent this error from happening?
Initially, we did this:
def exists(element: String, list: List[String]): Boolean =
if (list.nonEmpty) {
SQL("select {element} in {list} as result")
.on('element -> element, 'list -> list)
.as(SqlParser.bool("result").single)
} else {
false
}
This works perfectly well, and has the added advantage that it doesn't hit the database at all.
Unfortunately, we don't remember to do this every time, and it seems that 1-2 times a month we're fixing an issue related to this.
An alternate solution we came up with was to use a NonEmptyList class instead of a standard List. This class must have at least one element. This works excellent, but again, people have not been diligent with always using this class.
So I'm wondering if there's an approach I'm missing that prevent this type of error better?
It looks like you've already found a way to resolve this problem - you have an exists() function which handles an empty list cleanly. The problem is that people are writing their own exists() functions which don't do that.
You need to make sure that your function is accessible as a utility function, so that you can reuse it whenever you need to, rather than having to rewrite the function.
Your problem is an encapsulation problem: the Anorm API is like an open flame and people can burn themselves. If you rely just on people to take precautions, someone will get burnt.
The solution is to restrict the access to the Anorm API to a limited module/package/area of your code:
Anorm API will be private and accessible only from very few places, where it is going to be easy to perform the necessary controls. This part of the code will expose an API
Every other part of the code will need to go through that API, effectively using Anorm in the "safe" way

PyQt - Use SQL directly with QSqlTableModel

I'm writing a simple student scores manager for practicing programming on PyQt (I don't want to use terrible Visual Basic anymore). But I had a big problem on choose data models.
I found QSqlTableModel first, it is a great model with auto-updating. The trouble is, I need to use a lot of SQL (JOIN, WHERE) to select data from database. QSqlTableModel has select() and filter() only.
Then I found QSqlQueryModel, but it is read only. So I rewrite its setData() method. So it is read-write now. Unfortunately, QSqlQueryModel less usable features than QSqlTableModel.
As you see, if I can using SQL with QSqlTableModel, I can resolve all my problems.
So...?
QSqlTableModel has the setQuery method, which you can use to set a custom query, something like:
model = QSqlTableModel()
query = QSqlQuery(your_query)
model.setQuery(query)
However, the Qt documentation states:
This function simply calls QSqlQueryModel::setQuery(query). You should normally not call it on a QSqlTableModel. Instead, use setTable(), setSort(), setFilter(), etc., to set up the query.

LINQ to Entities does not recognize the method [Type] GetValue[Type]

I've a simple class like this:
Public Class CalculationParameter{
public Long TariffId{get;set;}
}
In a workflow activity, I've an Assign like this:
(From tariffDetail In db.Context.TariffDetails
Where tariffDetial.TariffId = calculationParameter.TariffId).FirstOrDefault()
Dto is passed to Activity as an Input Argument.
It raise following error and I'm wondering how to assign Id. Any Idea?
LINQ to Entities does not recognize the method 'Int64
GetValue[Int64](System.Activities.LocationReference)' method, and this
method cannot be translated into a store expression.
How can I assign the calculationParameter.TariffId to tariffDetial.TariffId?!
UPDATE:
Screen shot attached shows that how I'm trying to assign calculationParameter.TariffId to tariffDetail.TariffId (car.Id = Dto.Id) and the query result should assign to CurrentTrafficDetail object.
Here's your problem. I don't know if there is a solution to it.
As you said in a (now deleted, unfortunately necessitating that I answer) comment, the exception you're getting is
LINQ to Entities does not recognize the method Int64 GetValue[Int64](System.Activities.LocationReference) method, and this method cannot be translated into a store expression.
in your Linq query, calculationParameter is a Variable defined on the workflow. That Variable is actually an instance that extends the type System.Activities.LocationReference and NOT CalculationParameter.
Normally, when the workflow executes, the LocationReference holds all the information it needs to find the value which is assigned to it. That value isn't retrieved until the last possible moment. At runtime, the process of retrieval (getting the executing context, getting the value, converting it to the expected type) is managed by the workflow.
However, when you introduce Linq into the mix, we have the issue you are experiencing. As you may or may not know, your expression gets compiled into the extension method version of the same.
(From tariffDetail In db.Context.TariffDetails
Where tariffDetial.TariffId = calculationParameter.TariffId)
.FirstOrDefault()
is compiled to
db.Context.TariffDetails
.Where(x => x.TariffId = calculationParameter.TariffId)
.FirstOrDefault();
When this executes, L2E doesn't actually execute this code. It gets interpreted and converted into a SQL query which is executed against the database.
As the interpreter isn't omniscient, there are a well defined set of limitations on what methods you can use in a L2S query.
Unfortunately for you, getting the current value of a LocationReference is not one of them.
TL:DR You cannot do this.
As for workarounds, the only thing I think you can do is create a series of extension methods on your data context type or add methods to your CalculationParameter class that you can call from within the Expression Editor. You can create your Linq to Entities queries within these methods, as all types will already have been dereferenced by the workflow runtime, which means you won't have to worry about the L2E interpreter choking on LocationReferences.
*Edit: A workaround can be found here (thanks to Slauma who mentioned this in a comment on the question)

Linq Update Problem

I'm having some problems updating the database using Linq...
Public Shared Function Save(ByRef appointment As MyLinq.Appointment, ByRef db As MyEntities) As Boolean
If appointment.id = 0 Then
db.AddToAppointments(appointment)
Else
db.AttachTo("Appointments", appointment)
'db.ApplyPropertyChanges("Appointments", appointment)
End If
Return db.SaveChanges() > 0
End Function
So Insert works fine, i have tryed both lines of code for the update with no sucesss... The first one goes ok but no update is performed, the second one throws an exception...
Can someone point out what i am missing?
EDIT:
Sorry for the late reply... I had some internet connection problems...
I had to "make it work", so now my update code is fecthing the record from the database, updating and then executing "SaveChanges" method. It works but I am not happy having to query the database to perform an Update... If you have any idea how I could do this without an update I would appreciate :)
Chris: It was a nice try, but my refresh method only allows me to choose "RefreshMode.ClientWins" or "RefreshMode.StoreWins" I tried with ClientWins with no success...
Razzie: I am sorry but i did not save the exception and it no longer occurs... It was saying that my record did not have a key associated (or something similar)
Jon Skeet: In Vb.Net we have to specify if the parameter goes ByVal or ByRef, we can't omit like in C#
The code you have doesn't look exactly like what I'm used to (linq to sql), but it does look a little similar; Is this Entity Framework?
I know with Linq to SQL, simply attaching an object to the data context isn't enough, you also have to make sure that the data context knows what the original values are so it knows which columns to update. In Linq to SQL that can be achieved like this:
db.Refresh(RefreshMode.KeepCurrentValues, appointment)
Maybe look around and see if you can achieve something similar in whatever framework you are using.
The ApplyPropertyChanges() call is important otherwise the item you are attaching is assumed to be in an unchanged state. However... for ApplyPropertyChanges to work properly the original object must exist in the ObjectContext which means either querying for it again (which I think you are now doing) or using the same object context that you originally pulled the item from.
Some more info here - http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.applypropertychanges.aspx