How to do this in nhibernate queryover - nhibernate

I need to do this in nhibernate QueryOver:
select distinct sc.* from [Security].[Commands] sc
inner join [Security].[SystemSubjects] ss on ss.Id = sc.Id
left outer join [Security].[SystemSubjectRoles] ssr on ssr.SystemSubjectId = ss.Id
left outer join [Security].[Roles] sr on sr.Id = ssr.RoleId
left outer join [Security].[UserRoles] ur on ur.IdRole = sr.Id
left outer join [Security].[User] su2 on su2.Id = ur.IdUser
left outer join [Security].SystemSubjectUsers ssu on ssu.SystemSubjectId = ss.Id
left outer join [Security].[User] su on su.Id = ssu.UserId
where (su2.Id = 1 or su.Id = 1)
So far I have done this:
var queryOverRoles = QueryOver.Of<Command>(() => cmdAlias)
.JoinAlias(() => cmdAlias.SystemSubjectRoles, () => ssRoleAlias, JoinType.LeftOuterJoin)
.JoinAlias(() => ssRoleAlias.Role, () => roleAlias, JoinType.LeftOuterJoin)
.JoinAlias(() => roleAlias.Users, () => userAlias, JoinType.LeftOuterJoin)
.JoinAlias(() => cmdAlias.SystemSubjectUsers, () => ssUserAlias, JoinType.LeftOuterJoin)
.JoinAlias(() => ssUserAlias.User, () => userAlias2, JoinType.LeftOuterJoin)
.TransformUsing(Transformers.DistinctRootEntity)
.Where(() => ssRoleAlias.SecurityPermission == SecurityPermission.Allow)
.And(() => (userAlias.Id == userId || userAlias2.Id == userId))
but this selects all (Select ) and I want only the Command object (select sc.).
If I try to add a projection to the query like this:
queryOverRole.Select(x=>x);
it throws this exception:
System.Exception was caught Message=Could not determine member
from x Source=NHibernate
StackTrace:
at NHibernate.Impl.ExpressionProcessor.FindMemberExpression(Expression
expression) in
d:\CSharp\NH\nhibernate\src\NHibernate\Impl\ExpressionProcessor.cs:line
189
at NHibernate.Criterion.QueryOver2.Select(Expression1[]
projections) in
d:\CSharp\NH\nhibernate\src\NHibernate\Criterion\QueryOver.cs:line
363
at Novatec.Persistence.Repositories.Implementations.UserRepository.GetAllowedUserCommands(Int32
userId) in
C:\Projects\EGrad\Main\Source\Novatec.E-Grad\Source\Novatec.Persistence\Repositories\Implementations\UserRepository.cs:line
140
at Novatec.Administracija.Services.Security.SecurityManager.AuthorizeUserAction(Int32
userId, String commandId) in
C:\Projects\EGrad\Main\Source\Novatec.E-Grad\Source\Novatec.Administracija.Services\Security\SecurityManager.cs:line
48
at Novatec.Framework.Infrastructure.Services.ServiceBase.ExecuteCommand(Int32
userId, String appId, ICommand
command) in
C:\Projects\EGrad\Main\Source\Novatec.E-Grad\Source\Novatec.Framework.Infrastructure\Services\ServiceBase.cs:line
94 InnerException:

Try this.... you need to specify which alias to select.
queryOverRole.Select(result => cmdAlias);

Related

nHibernate join alias projecting some fields

I have the following query in nHibernate, which works really well.
Table1 table1Alias = null;
Table2 table2Alias = null;
Table3 table3Alias = null;
Table4 table4Alias = null;
Table5 table5Alias = null;
Table6 table6Alias = null;
var resultTable = session.QueryOver<Table1>()
.JoinAlias(x => x.Table2, () => table2Alias, NHibernate.SqlCommand.JoinType.LeftOuterJoin)
.JoinAlias(() => table2Alias.Table3, () => itemDesctable3AliasriptionAlias, NHibernate.SqlCommand.JoinType.LeftOuterJoin)
.JoinAlias(() => table2Alias.Table4, () => table4Alias, NHibernate.SqlCommand.JoinType.LeftOuterJoin)
.JoinAlias(x => x.Table5, () => table5Alias, NHibernate.SqlCommand.JoinType.LeftOuterJoin)
.JoinAlias(() => table5Alias.Table6, () => table6Alias, NHibernate.SqlCommand.JoinType.LeftOuterJoin)
.Where(x => x.Id == inputId)
.TransformUsing(Transformers.DistinctRootEntity)
.SingleOrDefault();
the problem is, i suspect i'll run into performance issues because
some of the tables have a lot of columns.
So here's the question, let's say I only need 1 field from "Table 5", but
fields from the rest of the table, do i have to do manual projections for all tables? or is there a way to only do manual projection for one table but left the rest as is?

Why does Projections.SubQuery messes up the rest of the query?

I want to get a following query using QueryOver
select
cg.CoverageGrpId,
SUM(cp.PremiumDueAmt) + SUM(cf.PremiumDueAmt) as TotalPremium,
SUM(pa.PaymentAllocAmt) as AllocatedAmount, p.ClientPolicyId,
(SELECT MAX(c2.CvrgExpDt) FROM Coverage c2 where c2.CoverageGrpId = cg.CoverageGrpId) as CoverageExpDate,
(SELECT MIN(c3.CvrgEffDt) FROM Coverage c3 where c3.CoverageGrpId = cg.CoverageGrpId) as CoverageEffDate
from dbo.vw_D_CoverageGroup cg
inner join dbo.vw_D_Batch b on b.PremCvrgBatchId = cg.PremCvrgBatchId
inner join dbo.vw_D_ClientPolicy p on p.ClientPolicyId = cg.ClientPolicyId
inner join dbo.vw_D_Bid bd on bd.BidId = p.BidId
inner join dbo.vw_D_CoverageGroupRow cgr on cgr.CoverageGrpId = cg.CoverageGrpId
inner join dbo.vw_D_Coverage c on c.CoverageGrpRowId = cgr.CoverageGrpRowId
left outer join dbo.vw_D_CoveragePremium cp on c.CoverageId = cp.CoverageId
left outer join dbo.vw_D_CoverageFee cf on cf.CoverageId = cp.CoverageId
left outer join dbo.vw_D_PaymentAllocation pa on pa.CoverageGrpId = cg.CoverageGrpId
where c.PrimaryInsuredId = 701112800 and b.BatchTypeCd = 'INDV'
group by cg.CoverageGrpId, p.ClientPolicyId
order by cg.CoverageGrpId, p.ClientPolicyId
Following is QueryOver that gets messed up once I add commented part.
var dto = new InsuredCoveragePayments();
Coverage coverage = null;
CoverageGroup coverageGroup = null;
CoverageGroupRow coverageGroupRow = null;
Batch batch = null;
PaymentAllocation paymentAllocation = null;
CoveragePremium coveragePremium = null;
CoverageFee coverageFee = null;
ClientPolicy clientPolicy = null;
Bid bid = null;
var l = _session.QueryOver<CoverageGroup>(() => coverageGroup)
.JoinAlias(cg => cg.Batch, () => batch)
.JoinAlias(cg => cg.ClientPolicy, () => clientPolicy)
.JoinAlias(cg => clientPolicy.Bid, () => bid)
.JoinAlias(cg => cg.PaymentAllocations, () => paymentAllocation, JoinType.LeftOuterJoin)
.JoinQueryOver(cg => cg.CoverageGroupRows, () => coverageGroupRow)
.JoinQueryOver(cgr => cgr.Coverages, () => coverage)
.JoinAlias(c => c.Premium, () => coveragePremium, JoinType.LeftOuterJoin)
.JoinAlias(c => c.Fees, () => coverageFee, JoinType.LeftOuterJoin)
.Where(x => coverage.PrimaryInsured.Id == 701112800)
.SelectList(list =>
list.Select(Projections.Group<CoverageGroup>(x => x.Id))
.WithAlias(() => dto.CoverageGroupId)
.Select(Projections.Group<ClientPolicy>(x => clientPolicy.PolicyNumber))
.WithAlias(() => dto.ClientPolicyNumber)
.Select(Projections.Sum<CoveragePremium>(x => coveragePremium.Amount))
.WithAlias(() => dto.PremiumAmount)
.Select(Projections.Sum<CoverageFee>(x => coverageFee.Amount))
.WithAlias(() => dto.FeeAmount)
.Select(Projections.Sum<PaymentAllocation>(x => paymentAllocation.AllocatedAmount))
.WithAlias(() => dto.AllocatedAmount))
//this messes the query up, it removes all 'select' parts and adds only subquery
//.Select(Projections.SubQuery(
// QueryOver.Of<Coverage>()
// .Where(c => c.CoverageGroup.Id == coverageGroup.Id)
// .SelectList(cl =>
// cl.SelectMin(c => c.CoverageEffectiveDates.Start.Value)
// .WithAlias(() => dto.CoverageFrom))))
//.Select(Projections.SubQuery
// (QueryOver.Of<Coverage>()
// .Where(c => c.CoverageGroup.Id == coverageGroup.Id)
// .SelectList(cl2 =>
// cl2.SelectMax(c => c.CoverageEffectiveDates.End.Value)
// .WithAlias(() => dto.CoverageTo))))
.TransformUsing(new AliasToBeanResultTransformer(typeof(InsuredCoveragePayments)))
.List<InsuredCoveragePayments>();
NHibernate generated output
Without SubQuery
SELECT this_.CoverageGrpId as y0_,
clientpoli2_.Year as y1_,
clientpoli2_.ClientNumber as y2_,
clientpoli2_.BidOptionNumber as y3_
sum(coveragepr7_.PremiumDueAmt) as y4_,
sum(coveragefe8_.PremiumDueAmt) as y5_,
sum(paymentall4_.PaymentAllocAmt) as y6_
FROM vw_D_CoverageGroup this_
inner join vw_D_CoverageGroupRow coveragegr5_ on this_.CoverageGrpId=coveragegr5_.CoverageGrpId
inner join vw_D_Coverage coverage6_ on coveragegr5_.CoverageGrpRowId=coverage6_.CoverageGrpRowId
left outer join vw_D_CoverageFee coveragefe8_ on coverage6_.CoverageId=coveragefe8_.CoverageId
left outer join vw_D_CoveragePremium coveragepr7_ on coverage6_.CoverageId=coveragepr7_.CoverageId
left outer join vw_D_PaymentAllocation paymentall4_ on this_.CoverageGrpId=paymentall4_.CoverageGrpId
inner join vw_D_Batch batch1_ on this_.PremCvrgBatchId=batch1_.PremCvrgBatchId
inner join vw_D_ClientPolicy clientpoli2_ on this_.ClientPolicyId=clientpoli2_.ClientPolicyId
inner join vw_D_Bid bid3_ on clientpoli2_.BidId=bid3_.BidId
WHERE coverage6_.PrimaryInsuredId = #p0
GROUP BY this_.CoverageGrpId, clientpoli2_.Year,clientpoli2_.ClientNumber,clientpoli2_.BidOptionNumber;
#p0 = 701112800 [Type: Int32 (0)]
With SubQuery (both uncommented)
SELECT
(SELECT max(this_0_.CvrgExpDt) as y0_
FROM vw_D_Coverage this_0_
WHERE this_0_.CoverageGrpId = this_.CoverageGrpId) as y0_
FROM vw_D_CoverageGroup this_
inner join vw_D_CoverageGroupRow coveragegr5_ on this_.CoverageGrpId=coveragegr5_.CoverageGrpId
inner join vw_D_Coverage coverage6_ on coveragegr5_.CoverageGrpRowId=coverage6_.CoverageGrpRowId
left outer join vw_D_CoverageFee coveragefe8_ on coverage6_.CoverageId=coveragefe8_.CoverageId
left outer join vw_D_CoveragePremium coveragepr7_ on coverage6_.CoverageId=coveragepr7_.CoverageId
left outer join vw_D_PaymentAllocation paymentall4_ on this_.CoverageGrpId=paymentall4_.CoverageGrpId
inner join vw_D_Batch batch1_ on this_.PremCvrgBatchId=batch1_.PremCvrgBatchId
inner join vw_D_ClientPolicy clientpoli2_ on this_.ClientPolicyId=clientpoli2_.ClientPolicyId
inner join vw_D_Bid bid3_ on clientpoli2_.BidId=bid3_.BidId
WHERE coverage6_.PrimaryInsuredId = #p0;#p0 = 701112800 [Type: Int32 (0)]
As you can see, when I uncomment the SubQuery, not only does it return other pieces in select, but it also only generates one subquery. Why?
Figured it out. In SubQuery parts, I had WithAlias at wrong place. It should look like this
var l = _session.QueryOver<CoverageGroup>(() => coverageGroup)
.JoinAlias(cg => cg.Batch, () => batch)
.JoinAlias(cg => cg.ClientPolicy, () => clientPolicy)
.JoinAlias(cg => clientPolicy.Bid, () => bid)
.JoinAlias(cg => cg.PaymentAllocations, () => paymentAllocation, JoinType.LeftOuterJoin)
.JoinQueryOver(cg => cg.CoverageGroupRows, () => coverageGroupRow)
.JoinQueryOver(cgr => cgr.Coverages, () => coverage)
.JoinAlias(c => c.Premium, () => coveragePremium, JoinType.LeftOuterJoin)
.JoinAlias(c => c.Fees, () => coverageFee, JoinType.LeftOuterJoin)
.Where(x => coverage.PrimaryInsured.Id == 701112800)
.SelectList(list =>
list
.Select(Projections.Group<CoverageGroup>(x => x.Id))
.WithAlias(() => dto.CoverageGroupId)
.Select(Projections.Group<ClientPolicy>(x => clientPolicy.PolicyNumber))
.WithAlias(() => dto.ClientPolicyNumber)
.Select(Projections.Sum<CoveragePremium>(x => coveragePremium.Amount))
.WithAlias(() => dto.PremiumAmount)
.Select(Projections.Sum<CoverageFee>(x => coverageFee.Amount))
.WithAlias(() => dto.FeeAmount)
.Select(Projections.Sum<PaymentAllocation>(x => paymentAllocation.AllocatedAmount))
.WithAlias(() => dto.AllocatedAmount)
.Select(Projections.SubQuery
(QueryOver.Of<Coverage>()
.Where(c => c.CoverageGroup.Id == coverageGroup.Id)
.SelectList(cl =>
cl.SelectMin(c => c.CoverageEffectiveDates.Start.Value))))
.WithAlias(() => dto.CoverageFrom)
.Select(Projections.SubQuery
(QueryOver.Of<Coverage>()
.Where(c => c.CoverageGroup.Id == coverageGroup.Id)
.SelectList(cl2 =>
cl2.SelectMax(c => c.CoverageEffectiveDates.End.Value))))
.WithAlias(() => dto.CoverageTo) )
.TransformUsing(new AliasToBeanResultTransformer(typeof(InsuredCoveragePayments)))
.List<InsuredCoveragePayments>();

NHibernate QueryOver join syntax for multiple tables

How would I rewrite this SQL using QueryOver? I'm not sure how QueryOver's join precedence and resolution works.
SELECT DISTINCT T1.*
FROM T1
LEFT JOIN T2
JOIN T3
ON T2.T3Key = T3.PrimaryKey
ON T1.PrimaryKey = T2.T1Key
LEFT JOIN T4
JOIN T5
ON T4.T5Key = T5.PrimaryKey
ON T1.PrimaryKey = T4.T1Key
WHERE T3.Criteria = #Criteria
OR T5.Criteria = #Criteria
http://www.sqlfiddle.com/#!3/affd13/5
Assuming you have all the relationships setup, it's a matter of setting up alias variable to use in the QueryOver...
T2 t2Alias = null;
T3 t3Alias = null;
T4 t4Alias = null;
T5 t5Alias = null;
int criteria = 1;
var results = Session.QueryOver<T1>()
.Left.JoinAlias(x => x.T2, () => t2Alias)
.Left.JoinAlias(() => t2Alias.T3, () => t3Alias)
.Left.JoinAlias(x => x.T4, () => t4Alias)
.Left.JoinAlias(() => t4Alias.T5, () => t5Alias)
.Where(Restrictions.Disjunction()
.Add(Restrictions.Where(() => t3Alias.Criteria == criteria))
.Add(Restrictions.Where(() => t5Alias.Criteria == criteria)))
.TransformUsing(Transformers.DistinctRootEntity)
.List();
I don't think you'll be able to nest those inner joins...but it looks like you'd get the same results with all left joins.

NHibernate Query subquery group by join back to main entity

Hello i'm trying to achieve the following SQL
SELECT this_.*
FROM WorkItems this_
WHERE this_.UserId = (
SELECT this_1_.y0_ as y0_
FROM
(
SELECT top 1 this_0_.UserId as y0_, count(this_0_.UserId) as y1_
FROM WorkItems this_0_
WHERE this_0_.StateId = 1 and this_0_.Type like 'Data'
GROUP BY this_0_.UserId
ORDER BY y1_ desc
) this_1_
);
so far i have manged to produce something fairly close. I'm missing the part where i just select out the userId.
heres the query so far
var subquery = QueryOver.Of<WorkItem>().Where(w => w.State == state)
.AndRestrictionOn(w => w.Type).IsLike(type, MatchMode.Exact)
.SelectList(list =>
list.SelectGroup(w => w.UserId)
.WithAlias(() => resultAlias.userId)
.SelectCount(w => w.UserId)
.WithAlias(() => resultAlias.count))
.OrderByAlias(() => resultAlias.count)
.Desc().Take(1);
var query =
CurrentSession.QueryOver<WorkItem>()
.WithSubquery
.WhereProperty(p => p.UserId)
.Eq(subquery);
Try this: -
var subquery = QueryOver.Of<WorkItem>().Where(w => w.State == state)
.AndRestrictionOn(w => w.Type).IsLike(type, MatchMode.Exact)
.SelectList(list => list.SelectGroup(w => w.UserId))
.OrderBy(Projections.Count<WorkItem>(x => x.UserId))
.Desc().Take(1);
var query = CurrentSession.QueryOver<WorkItem>()
.WithSubquery
.WhereProperty(p => p.UserId)
.Eq(subquery);

How can I convert SQL to LINQ-to-SQL

SELECT Cities.CityName, Customers.CustomerName, SUM(Bills.Sarees)
FROM Bills INNER JOIN
Customers ON Bills.CustomerID = Customers.CustomerID INNER JOIN
Cities ON Customers.CityID = Cities.CityID
Group by CustomerName, CityName
I have tried to make it as below.... but I am unable to insert group by clause within
var query = db.Bills.Join(db.Customers, c => c.CustomerID, p => p.CustomerID, (c, p) => new
{
c.Customer.CustomerID,
c.Customer.CustomerName,
c.Customer.City.CityName,
c.Customer.Mobile1,
c.Customer.Mobile2,
c.Customer.Telephone,
c.Customer.Email,
c.Sarees
});
Looking at your SQL, you need something like this I guess:
var query = db.Bills
.Join(db.Customers, b => b.CustomerID, c => c.CustomerID, (b, c) => new
{
b.Sarees,
c.CustomerName,
c.CityID
})
.Join(db.Cities, j => j.CityID, c => c.CityID, (j, c) => new
{
j.Sarees,
j.CustomerName,
j.CityID,
c.CityName
})
.GroupBy(o => new { o.CustomerName, o.CityName })
.Select(o => new { o.Key.CityName, o.Key.CustomerName, Sum = o.Sum(i => i.Sarees) });