Reputation: 15334
I'm trying to do what seems like a simple query for the number of Products
produced by each Manufacturer
, but NHibernate isn't generating T-SQL that MS SQL Server finds valid.
session.Query<Product>()
.GroupBy(p => p.Manufacturer)
.Select(grp => new {Mftr = grp.Key.Name, ProductCount = grp.Count()})
.ToList();
This seems dead simple, but the SQL statement that NHibernate generates doesn't include all the necessary column names, so it fails when running against a SQL Server 2008 or SQL Server CE database. If I point the same code to an in-memory SQLite database, it works fine.
More information is below, and I also created a small console application that demonstrates my problem. How do I fix this problem?
select manufactur1_.Id,
cast(count(*) as INT),
manufactur1_.Id,
manufactur1_.Name
from "Product" product0_
left outer join "Manufacturer" manufactur1_
on product0_.Manufacturer_id=manufactur1_.Id
group by manufactur1_.Id -- Where's manufactur1_.Name?
public class Product {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
}
public class Manufacturer {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class ProductMap : ClassMap<Product> {
public ProductMap() {
Id(x => x.Id).GeneratedBy.HiLo("1");
Map(x => x.Name);
References(x => x.Manufacturer).Cascade.SaveUpdate().Not.Nullable();
}
}
public class ManufacturerMap : ClassMap<Manufacturer> {
public ManufacturerMap() {
Id(x => x.Id) .GeneratedBy.HiLo("1");
Map(x => x.Name);
}
}
Upvotes: 2
Views: 369
Reputation: 26940
Here's a QueryOver version...
//alias variables
Manufacturer m = null;
ManufacturerProducts dto = null;
var result = Session.QueryOver<Product>
.Left.JoinAlias(x => x.Manufacturer, () => m)
.SelectList(list => list
.SelectGroup(() => m.Id).WithAlias(() => dto.Id)
.SelectGroup(() => m.Name).WithAlias(() => dto.Name)
.SelectCount(x => x.Id).WithAlias(() => dto.ProductCount))
.TransformUsing(Transformers.AliasToBean<ManufacturerProducts>())
.List<ManufacturerProducts>();
Upvotes: 2