NHibernate Linq Group By fails to group properly in SQL Server - linq

I have the following LINQ query which uses NHibernate against a SQL Server backed repository...
var casesByCaseOwner = this.preGrantDetailRepository.All
.Where(x => x.CaseFileLocation.Id == cflId)
.GroupBy(x => x.CaseOwner)
.Select(x => new StagSummaryForCfItem
{
Id = x.Key.Id,
Description = x.Key.Name,
NumberOfCases = x.Count(),
UninvoicedNetFee = x.Sum(y => y.UninvoicedNetFee),
UninvoicedDisbursement = x.Sum(y => y.UninvoicedDisbursement)
}).AsEnumerable();
However, it complains that SQL Server is unable to group by the CaseOwner.Name column because it is not contained in the select list or group clause. Coming from a database world I understand that error, however, I'm not sure how to force NHibernate to group by both Id and Name but still have the CaseOwner entity available to me in my Select.

I found the answer finally...
var casesByCaseOwner = this.preGrantDetailRepository.All
.Where(x => x.CaseFileLocation.Id == cflId)
.GroupBy(x => new { x.CaseOwner.Id, x.CaseOwner.Name })
.Select(x => new StagSummaryForCfItem
{
Id = x.Key.Id,
Description = x.Key.Name,
NumberOfCases = x.Count(),
UninvoicedNetFee = x.Sum(y => y.UninvoicedNetFee),
UninvoicedDisbursement = x.Sum(y => y.UninvoicedDisbursement)
}).AsEnumerable();
return casesByCaseOwner;
This works nicley, it turns out I need to project a new entity with the properties I want to group on.

Related

How to count distinct

I'm implementing ASP.NET Core project and have a query like the following for finding count of distinct userId per operatorName, however it shows me error for the line count distinct after running the project:
var activeUserPerOperatorCount = requests.GroupBy(x => new { operatorName = x.Operator.Name, x.UserId }).Select(x => new
{
userIds = x.Key.UserId,
operatorNames = x.Key.operatorName,
activeUserPerOperatorCount = x.Select(l => l.UserId).Distinct().Count()
}).ToList();
I appreciate if anyone helps me how can I find distinct count of userId per operatorName in my query.
ok, the correct query is like the following and it works correctly:
var activeUserPerOperatorCount = requests.GroupBy(x => new { operatorName = x.Operator.Name}).Select(x => new
{
operatorNames = x.Key.operatorName,
activeUserPerOperatorCount = requests.Select(l => l.UserId).Distinct().Count()
}).ToList();

How can I add Sum from another Table in my Model?

So I have my View setup like this in the controller:
public ActionResult View(Guid projectID)
{
OnboardModel model = context.onboard_projectInfos.Where(x => x.projectID == projectID).Select(x =>
new OnboardModel()
{
propertymanagername = x.propertymanagername,
propertymanagercontactemail = x.propertymanagercontactemail,
date_modified = (DateTime)x.date_modified,
projectmanagercontactnumber = x.projectmanagercontactnumber,
Developer = x.onboard_projectCreate.Developer,
status1 = x.onboard_projectCreate.status1,
ProjectName = x.onboard_projectCreate.ProjectName
}).SingleOrDefault();
var pix = projectID.ToString();
context.onboard_BuildingInfos.Where(x => x.buildprojectID == pix).GroupBy(x => x.buildprojectID).Select(g => {
model.totalres = g.Sum(b => b.numberofres);
model.totalcom = g.Sum(b => b.numberofcommer);
});
return View(model);
}
Problem is grabbing the sum of numberofres and numberofcommer from BuildingInfos.
Using .Select gives me the error:
Error CS0411 The type arguments for method 'Queryable.Select(IQueryable, Expression>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
How to I write this LINQ statement correctly?
Thanks.
You cannot modify an object within a select (you can only create a new object). Further, you can't add new properties to an existing object.
We'll assume that OnboardModel defines the totalres and totalcom properties.
var query = context.onboard_BuildingInfos
.Where(x => x.buildprojectID == pix)
.GroupBy(x => x.buildprojectID);
foreach(var g in query)
{
model.totalres = g.Sum(b => b.numberofres);
model.totalcom = g.Sum(b => b.numberofcommer);
}

Replacing empty values with a default value in a Linq to Entities query

In the Linq to Entities query below I need to place a default value in the x.Number in the returned value if the query returns 0 OfficeTelephone objects. I have tried
x.Number??"555-1212" but that throws an error.
from c in Contacts
.Where(a => a.LastName.Contains("ANDUS")).Take(10)
select new
{
Id = c.Id,
OfficeTelephone = c.Telephones.Where(a=>a.TelephoneType.Name.Contains("Office")).Select(x => new { x.AreaCode, x.Number, x.TelephoneType, x.Primary })
}
I've tried something like:
from c in Contacts
.Where(a => a.LastName.Contains("ANDUS")).Take(10)
select new
{
Id = c.Id,
OfficeTelephone = c.Telephones
.Where(a=>a.TelephoneType.Name.Contains("Office"))
.Select(x => new { x.AreaCode, x.Number, x.TelephoneType, x.Primary })
.DefaultIfEmpty()}
But I'm not sure how to push a default object into the DefaultIFEmpty()
Use DefaultIfEmpty and pass a default instance with those value which you would want by default i.e. if no rows are returned.
try it like this:
Contacts.Where(a=>a.LastName.Contains("ANDUS"))
.Take(10)
.Select(x => new
{
Id = x.Id,
OfficeTelephone = x.Telephones
.Where(a=> a.Telephone.Name.Contains("Office"))
.Select(b=> new Telephone
{
b.AreaCode,
b.Number,
b.TelephoneType,
b.Primary
})
.DefaultIfEmpty(new Telephone())
});
where I've assumed that typeof(x.Telephones) == typeof(List<Telephone>)

Linq select subquery

As the title states, I'm trying to perform a select subquery in Linq-To-SQL. Here's my situation:
I have a database view which returns the following fields:
SourceId
LicenseId
LicenseName
CharacteristicId
CharacteristicName
Now I want to be able to store this in a model of mine which has the following properties
Id
Name
Characteristics (this is List which has Id, Name and Icon => Icon is byte[])
Here's the query I wrote which doesn't work:
var licensesWithCharacteristics =
_vwAllLicensesWithAttributesAndSourceIdRepository.GetAll()
.Where(x => x.SourceID == sourceId)
.Select(a => new LicenseWithCharacteristicsModel()
{
LicenseId = a.LicenseId,
LicenseName = a.LicenseName
,CharacteristicList = _vwAllLicensesWithAttributesAndSourceIdRepository.GetAll()
.Where(x => x.LicenseId == a.LicenseId)
.Select(c => new CharacteristicModel { Id = c.CharacteristicID, Name = c.CharacteristicName, Icon = c.Icon })
.Distinct().ToList()
})
.Distinct().ToList();
How would you solve this? I'm trying to do this in one query to keep my performance up, but I'm kind of stuck.
Your sample query and models are not that coherent (where does Icon come from, Characteristics or CharacteristicList), but anyway.
I do this in two parts, you can of course regroup this in one query.
I enumerate the result after the grouping, you may try to do without enumerating (all in linq to sql, but not sure it will work).
var groupedResult =
_vwAllLicensesWithAttributesAndSourceIdRepository.GetAll()
.Where(x => x.SourceID == sourceId)
.GroupBy(m => new {m.LicenseId, m.LicenseName})
.ToList();
var results = groupedResult.Select(group => new LicenseWithCharacteristicsModel {
LicenseId = group.Key.LicenseId,
LicenseName = group.Key.LicenseName,
Characteristics = group.Select(m=> new CharacteristicModel {
Id = m.CharacteristicId,
Name = m.CharacteristicName
}).ToList()
});
in "single query"
_vwAllLicensesWithAttributesAndSourceIdRepository.GetAll()
.Where(x => x.SourceID == sourceId)
.GroupBy(m => new {m.LicenseId, m.LicenseName})
.Select(group =>
new LicenseWithCharacteristicsModel
{
LicenseId = group.Key.LicenseId,
LicenseName = group.Key.LicenseName,
Characteristics = group.Select(m =>
new CharacteristicModel
{
Id = m.CharacteristicId,
Name = m.CharacteristicName
}).ToList()
});

could not resolve property (complex properties)

I have a asp.net mvc application with NHibernate and I do not know how to resolve a problem to query some data. I have this query:
// create query
var query = session.QueryOVer<Laudo>().Fetch(x => x.Equipament).Eager;
// add some filters
if (idEquipament.HasValue)
query = query.And(x => x.Equipament.Id == idEquipament.Value);
//I got the error here...
if (idCompany.HasValue)
query = query.And(x => x.Equipament.Company.Id == idCompany.Value);
When I try to execute this query, I've got an exception with this message:
"could not resolve property: Equipament.Company.Id of: DomainModel.Laudo"
what can I do to fix this problem?
Thanks
You cannot use another entity property like that. NHibernate expects expression that can be evaluated to property of the current entity. You need to use JoinQueryOver or JoinAlias to join another entity, and perform where after that.
With JoinQueryOver:
// ...
query = query.JoinQueryOver(x => x.Equipment)
.JoinQueryOver(x => x.Company)
.Where(c => c.Id == idCompany.Value);
With JoinAlias:
Equipment equipment = null;
Company company = null;
// ...
query = query.JoinAlias(x => x.Equipment, () => equipment)
.JoinAlias(() => equipment.Company, () => company)
.Where(() => company.Id == idCompany.Value);
Some more info:
What is the difference between JoinQueryOver and JoinAlias?
What can be used as a NHibernate QueryOver alias?
Complex nHibernate QueryOver expression
The tags chosen for your question make me think you didn't want to use QueryOver, but LINQ.
This is achieved by using the extension method Query, in the NHibernate.Linq namespace:
var query = session.Query<Laudo>().Fetch(x => x.Equipament);
if (idEquipament.HasValue)
query = query.Where(x => x.Equipament.Id == idEquipament.Value);
if (idCompany.HasValue)
query = query.Where(x => x.Equipament.Company.Id == idCompany.Value);

Resources