NHibernate casts to decimal when doing AVG - fluent-nhibernate

I use nhibernate 3 with fluent mapping and MySQL5Dialect. I do grouping and trying to get average value:
var group = new TotalStatistic();
SelectList(s => s
.SelectGroup(t => t.RegistryName).WithAlias(() => group.Name)
.SelectAvg(t => t.Value).WithAlias(() => group.Average))
.TransformUsing(Transformers.AliasToBean<TotalStatistic>());
But it generates sql query that contains cast to decimal and I get only zeroes in results instead of something like "0.0035" I suppose to get.
SELECT ... avg(cast(this_.Value as DECIMAL)) as y1_ ...

Related

Jenssegers / select('column') returns more columns than the one specified in the select

I have the following issue with jenssegers query builder (I'm a new user):
print_r(DB::table($tablename)->where('_id',$_id)->select($table_structure_record['field'])->get());
returns me more than one column, despite only one column is specified in the select statement:
Array ( [0] => Array ( [_id] => MongoDB\BSON\ObjectID Object ( [oid] => 5780b81d93f7fb0e00d0f252 ) [collection] => structure ) )
My expected result would be only ([collection] => structure) , I don't understand why i also get "[_id] => MongoDB\BSON\ObjectID Object ( [oid] => 5780b81d93f7fb0e00d0f252 )"
Can someone help me ? Despite many searches, it seems select statement is supposed to return ONLY the columns specified, not any other !
MongoDb always returns the _id field unless you specifically set it not to while making the request(MongoDb Limit Fields to Return from Query Documentation).
You can try using project instead.Then it will be something like this:
DB::table($tablename)->where('_id',$_id)->project([$table_structure_record['field'] => 1, "_id" => 0])->get());

TYPO3 doesn't respect field names in JOIN query

I'm trying to fetch a JOIN query in TYPO3 using createQuery and $query->statement(...), but get odd results. Can someone explain to me why TYPO3 doesn't include table names as a prefix to column names in a JOIN query? Does this conflict with the ORM? Can I in anyway speed up a query of multiple 1:N-relations?
Example:
SELECT
client.name, project.name
FROM
client
LEFT JOIN
project ON project.client = client.uid
The PHP code from client repository:
$query = $this->createQuery();
$query->statement($statement);
$query->getQuerySettings()->setReturnRawQueryResult(true);
var_dump($query->execute());
The result prints out only names of the projects:
array (size=294)
0 =>
array (size=1)
'name' => string 'Projectname1' (length=21)
1 =>
array (size=1)
'name' => string 'Projectname2' (length=20)
2 =>
array (size=1)
'name' => string 'Projectname3' (length=32)
EDIT: This might be standard SQL behaviour.
Use aliases for fields:
SELECT
client.name client_name, project.name project_name
FROM
client
LEFT JOIN
project ON project.client = client.uid

Convert Sql query with Group by and Having clause to Linq To Sql query in C#

I need help to convert following ql query to Linq to Sql query.
select Name, Address
from Entity
group by Name, Address
having count(distinct LinkedTo) = 1
Idea is to find all unique Name, Address pairs who only have 1 distinct LinkedTo value. Remember that there are other columns in the table as well.
I would try something like this:
Entity.GroupBy(e => new { e.Name, e.Address})
.Where(g => g.Select(e => e.LinkedTo).Distinct().Count() == 1)
.Select(g => g.Key);
You should put a breakpoint after that line and check the SQL that is generated to find what is really going to the database.
You could use:
from ent in Entities
group ent by new { ent.Name, ent.Address } into grouped
where grouped.Select(g => g.LinkedTo).Distinct().Count() == 1
select new { grouped.Key.Name, grouped.Key.Address }
The generated SQL does not use a having clause. I'm not sure LINQ can generate that.

get only one row and one column from table using nhibernate

I have query:
var query = this.session.QueryOver<Products>()
.Where(uic => uic.PageNumber == nextPage[0])
.SingleOrDefault(uic => uic.ProductNumber)
But this query result is type Products. It is possible that result will be only integer type of column ProductNumber ?
Try something like this:
var query = this.session.QueryOver<Products>()
.Where(uic => uic.PageNumber == nextPage[0])
.Select(uic => uic.ProductNumber)
.SingleOrDefault<int>();
Since you need a single primitive type value, you can do .Select to define the result column, and then do .SingleOrDefault to get the only result. For complex types, you'd need to use transformers.
You can find more info about QueryOver in this blog post on nhibernate.info: http://nhibernate.info/blog/2009/12/17/queryover-in-nh-3-0.html
You can use Miroslav's answer for QueryOver, but this would look cleaner with LINQ:
var productNumber = session.Query<Products>()
.Where(uic => uic.PageNumber == nextPage[0])
.Select(uic => uic.ProductNumber)
.SingleOrDefault();
Notice you don't need a cast, as the Select operator changes the expression type to the return type of its parameter (which is the type of ProductNumber).

Truncate DateTime in NHibernate QueryOver SelectGroup

I have a fairly run-of-the-mill QueryOver query containing the following,
.SelectList(list => list
.SelectGroup(() => txn.GroupField)
.SelectGroup(() => txn.Date))
.List<object[]>()
This query works as expected however I now have a requirement to group by the truncated Date as some of the Date's for these objects may contain a time component. This seems like it should be a trivial change but I can't find a way that is supported by NHibernate.
The obvious solution would be the change below but is not supported.
.SelectGroup(() => txn.Date.Date))
Any ideas?
Thanks
Your QueryOver could look like this:
Status alias = null;
var query = QueryOver.Of(() => alias)
.Select(Projections.GroupProperty(
Projections.SqlFunction("date", NHibernateUtil.Date, Projections.Property(() => alias.Date))));
Output (pseudo sql):
SELECT
...
FROM [Status] this_
GROUP BY dateadd(dd, 0, datediff(dd, 0, this_.Date))
Hope this helps, cheers!
You might want to add a helper property to your map, using the Formula command, to be able to use the date (instead of datetime) in queries.
here's an example from my code; it uses a decimal value, but this works fine with any subquery:
model class has this property, to be mapped to a formula:
public virtual decimal Profit
{
get { return this.SellPrice - this.Cost; }
set { return; }
}
fluentNHibernate map:
//SellPrice and Cost are columns in the object's table
Map(v => v.Profit).Formula("(SellPrice - Cost)"); // this field is calculated, not read
be sure to put the formula between () brackets though.
If you'd make your formula a select query that trunks the datetime into a date, you could then group by that property in your query.