How can I convert SQL to LINQ-to-SQL - 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) });

Related

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>();

C# + LINQ - inner join

Table: one
Column (PK): employee_ssn
Column: employee_active bit
Table: two
Column (pk): date
Column (FK): employee_ssn
Column: total_income
Column: total_expenses
Working Linq code to sum total_income and total_expenses for the year, per employee:
var SumOfSections = db.two
.Select(x => x)
.Where(x => x.employee_ssn.Equals(xxxxxxxxx))
.Where(x => x.Date.Year.Equals(year))
.GroupBy(x => x.Date)
.Select(g => new
{
Total_Income = g.Sum(x => x.total_expenses),
Total_Expenses= g.Sum(x => x.total_income)
})
.ToArray();
I need to incorporate INNER JOIN to the above to only include active employees. Working SQL:
select two.total_income,total_expenses
from two
INNER JOIN one
ON one.SSN = two.SSN
WHERE one.Active = 1 AND two.Date='1/1/2014' AND two.SSN='xxxxxxxxx';
How can I modify my linq code to what my sql code is doing?
var SumOfSections = (from t in db.two
join o in db.one on t.employee_ssn equald o.employee_ssn
where t.employee_ssn = "xxxxxxxxx" && o.employee_active == true
group t by t.date into g
select new {
Total_Income = g.Sum(x => x.total_expenses),
Total_Expenses= g.Sum(x => x.total_income)
}).ToArray();
I used query syntax because it seems to be more readable.
You can also continue with the notation you are using:
var SumOfSections = db.two.Join(db.one, o=>o.employee_ssn, t=>t.employee_ssn, (o,t)=>new {One = o, Two = t)
.Select(x => x)
.Where(x => x.Two.employee_ssn.Equals(""))
.Where(x => x.Two.date.Year.Equals(1234))
.Where(x=> x.One.employee_active == true)
.GroupBy(x => x.Two.date)
.Select(g => new
{
Total_Income = g.Sum(x => x.Two.total_expenses),
Total_Expenses = g.Sum(x => x.Two.total_income)
})
.ToArray();

How to use the group join result to join another tables using LINQ?

I am not able to use the result of group join and then further applying the join with other tables.
My SQL query is :
SELECT *
FROM
[dummy_database].[dbo].[MA] M
INNER JOIN
SN.dbo.A A ON A.ApplicantMAId = M.MAId
INNER JOIN
SN.dbo.SP SP ON SP.PropertyMAId = M.MAId
INNER JOIN
SN.dbo.MCC CC ON CC.MAId = m.MAId
INNER JOIN
SN.dbo.MLSTN T ON T.MAT_ID = M.MAId
INNER JOIN
(SELECT
MAX(MAT_DATE) AS MaxDate,
MAT_ID
FROM
[SN].[dbo].[MLSTN]
GROUP BY
MAT_ID) Q ON Q.MAT_ID = M.MAId
and what I have done so far is:
var q = (from ml in context.MLSTN
group ml by ml.MAT_ID into g
let maxdate = g.Max(date => date.MAT_DATE)
select new
{
MortgId = g.Key,
TrackingDate = g.FirstOrDefault(val => val.MAT_DATE == maxdate).MAT_DATE
}
);
but now this result is not at all further used by me to create a join with other tables. I want to ask how to join further? Any clue?
You need something like this:
var groups = context.MLSTN
.GroupBy(x => x.MAT_ID)
.Select(g => new
{
MAT_ID = g.Key,
MaxDate = g.Max(date => date.MT_DATE)
});
var result = context.MA
.Join(context.A,
m => m.MA_ID,
a => a.MA_ID,
(m, a) => new
{
MA = m,
A = a
})
.Join(context.SP,
x => x.MA.MAId,
sp => sp.PropertyMAId,
(x, sp) => new
{
MA = x.MA ,
A = x.A,
SP = sp
})
.Join(context.MCC,
x => x.MA.MAId,
cc => cc.MAId,
(x, cc) => new
{
MA = x.MA ,
A = x.A,
SP = x.SP,
MCC = cc
})
.Join(context.MLSTN,
x => x.MA.MAId,
t => t.MAT_ID,
(x, t) => new
{
MA = x.MA ,
A = x.A,
SP = x.SP,
MCC = x.MCC,
MLSTN = t
})
.Join(groups,
x => x.MA.MAId,
g => g.MAId,
(x, g) => new
{
MA = x.MA ,
A = x.A,
SP = x.SP,
MCC = x.MCC,
MLSTN = t,
MLSG = g
});

Equivalent of this SQL query in LINQ using Lambda

What is the correct lambda syntax for the following query?
SELECT a.Title, Count(b.Id) FROM a INNER JOIN b on a.Id = b.FK_Id GROUP BY a.Title
I know how to use join, but don't have any idea how to use aggregate and group by in this situation.
Thank you.
Looks to me like:
var query = from a in TableA
join b in TableB on a.Id equals b.FkId
group b by a.Title into g
select new { Title = g.Key, Count = g.Count() };
Or in non-query syntax:
var query = TableA.Join(TableB, a => a.Id, b => b.FkId, (a, b) => new { a, b })
.GroupBy(z => z.a.Title, z => z.b)
.Select(g => new { Title = g.Key, Count = g.Count() });

How to do this in nhibernate queryover

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);