How to convert this T-SQL query to LINQ syntax? - linq

I´m trying to write below T-SQL query in LINQ. But I can´t figure out the syntax. Please help me out here.
SELECT
MONTH( O.Date) AS Month,
SUM( P.Price * PO.Quantity ) AS OrderSumPerMonth
FROM
Products P
INNER JOIN ProductOrders PO ON P.ProductId = PO.ProductId
INNER JOIN Orders O ON PO.OrderId = O.OrderId
GROUP BY
MONTH( O.Date );

var query = dbContext.ProductOrders
.GroupBy( po => new { po.Order.Date.Year, po.Order.Date.Month } )
.Select( grp => new
{
grp.Key,
OrderSumPerMonth = grp.Sum( po => po.Product.Price * po.Quantity )
} );
foreach(var row in query) {
WriteLine( "{0}/{1} - {2:C}", row.Key.Year, row.Key.Month, row.OrderSumPerMonth );
}

Related

How to read data from a nested select query linq

I have a query like the following which is of type linq.
var querymiangin = (from t1 in _context.Apiapplicant
join t2 in _context.ApiApplicantHistory on t1.Id equals t2.ApiApplicantId
join t3 in _context.EntityType on t2.LastReqStatus equals t3.Id
where t1.IsDeleted == false && t1.LastRequestStatus == t2.Id && t3.Name == "granted"
select new { A = t1, B = t2, Year = t1.ApiRequestDate.Substring(0, 4), Month = t1.ApiRequestDate.Substring(5, 2) } into joined
group joined by new { joined.Year, joined.Month, joined.B.LastReqStatus } into grouped
select grouped.Select(g => new { ApiReqDate = g.A.ApiRequestDate, ApiDate = g.B.Date, ApiLastReqStatus = g.B.LastReqStatus, ApiYear = g.Year, ApiMonth = g.Month })).ToList();
In the select part, ApiReqDate and ApiDate has multiple records. Now my problem is for each group of month and year, I have multiple ApiDate and ApiReqDate records and I want for each group based on a condition (t1.LastRequestStatus == t2.Id && t3.Name == "granted") by using GetPersianDaysDiffDate() method, obtain the difference between ApiReqDate and its related ApiDate records for each month and then find their average in that month.
For doing that, I have written code like this:
var avgDateDiff = querymiangin.DefaultIfEmpty()
.GroupBy(x => new { x.ApiYear, x.ApiMonth }, (key, g) => new
{
key.ApiYear,
key.ApiYear,
Avg = g.Average(y => GetPersianDaysDiffDate(y.ApiReqDate,y.ApiDate))
})
.ToList();
But the problem is each parameter x.ApiYear, x.ApiMonth,y.ApiReqDate,y.ApiDate are unknown and it shows me error. I appreciate if anyone can suggest me a solution for that.
1 - For the first request querymiangin, you don't need to group by statement, change little the code to :
var querymiangin = (from t1 in Apiapplicant
join t2 in ApiApplicantHistory on t1.Id equals t2.ApiApplicantId
join t3 in EntityType on t2.LastReqStatus equals t3.Id
where t1.IsDeleted == false && t1.LastRequestStatus == t2.Id && t3.Name == "granted"
select new
{
ApiReqDate = t1.ApiRequestDate,
ApiDate = t2.Date,
ApiYear = t1.ApiRequestDate.Substring(0, 4),
ApiMonth = t1.ApiRequestDate.Substring(5, 2)
}).ToList();
2 - For the second query avgDateDiff, use GroupBy by ApiYear and ApiMonth and calculate the Average, like :
var avgDateDiff = querymiangin
.GroupBy(x => new { x.ApiYear, x.ApiMonth }, (key, g) => new
{
key.ApiYear,
key.ApiMonth,
Avg = g.Average(y => GetPersianDaysDiffDate(y.ApiReqDate, y.ApiDate))
}).ToList();
I hope you find this helpful.

C# linq query OUTER APPLY with SUM

Trying to convert a SQL Query to Linq:
SELECT GrossInvoiceAmount, C.SumOfPayments
FROM invoice
OUTER APPLY(
SELECT SUM(SumOfPayments) AS SumOfPayments FROM vw_sumOfPayments
WHERE vw_sumOfPayments.PaymentDate = '01/01/2010 00:00:00'
AND vw_sumOfPayments.InvoiceId = invoice.InvoiceId
) C
WHERE LastTransmitDate = '01/01/2010 00:00:00'
I have this in my C# code. It runs and gives results, but the invoice.GrossInvoiceAmount amount is wrong. Any ideas? Thanks.
var InvoiceQuery = (from invoice in this.Context.Invoices
join payment in this.Context.vw_sumOfPayments.Where(pay => DbFunctions.TruncateTime(pay.PaymentDate) >= startdate
&& DbFunctions.TruncateTime(pay.PaymentDate) <= enddate)
on invoice.InvoiceID equals payment.InvoiceID into pays
select new InvoiceModel{
InvoiceTypeId = invoice.InvoiceTypeId,
InvoiceNumber = invoice.InvoiceNumber,
InvoiceDate = invoice.InvoiceDate,
InvoiceAmount = invoice.GrossInvoiceAmount,
PaymentAmount = pays.AsEnumerable().Sum(o => o.SumOfPayments)
});

Using subquery in entity framework

I am trying to write the entity framework linq query to generate the following SQL. But I am not sure how to use subqueries with entity framework.
The Sql I want to generate is:
Declare #StartDate Datetime2; Set #Startdate = '2014-Feb-16 09:52'
Declare #EndDate Datetime2; Set #Enddate = '2014-Feb-18 09:52'
SELECT
[D].[RefId]
,[D].[StatusId]
,[D].[StatusDate]
,[D].[Reference]
,[RSC].[Event]
,[RSC].[Information]
,[RSC].[CreatedDate]
FROM (
SELECT
[R].[RefId]
,[R].[StatusId]
,[R].[StatusDate]
,[I].[Reference]
,(SELECT TOP 1
[RSC].[ChangeId]
FROM
[dbo].[StateChangeTable] AS [RSC] (nolock)
WHERE
[RSC].[RefId] = [R].[RefId]
ORDER BY
[RSC].[ChangeId] DESC) AS [LastChangeId]
FROM
[dbo].[Table1] AS [R] (nolock)
INNER JOIN
[dbo].[Table2] AS [I] (nolock)
ON
[R].[RefId] = [I].[RefId]
WHERE
[R].[StatusId] IN (4, 6)
AND [R].[StatusDate] between #StartDate and #EndDate
) AS [D]
INNER JOIN
[dbo].[StateChangeTable] AS [RSC] (nolock)
ON
[D].[LastChangeId] = [RSC].[ChangeId
]
And the code I wrote till now is:
return this.DbContext.Table1
.Join(this.DbContext.Table2, rc => rc.RefId, ri => ri.RefId, (rc, ri) => new { rc, ri })
.Join(this.DbContext.StateChangeTable, request => request.ri.RefId, rsc => rsc.RefId, (request, rsc) => new {request, rsc})
.Where(r => (r.rsc.ChangeId == ((from rsc in this.DbContext.StateChangeTable
orderby rsc.ChangeId descending
select rsc.ChangeId).FirstOrDefault())) &&
(r.request.rc.StatusId == 4 || r.request.rc.StatusId == 6) &&
(r.request.rc.StatusDate >= startDateTime && r.request.rc.StatusDate <= endDateTime))
.Select(requestDetails => new StatusDetail
{
RefId = requestDetails.request.rc.RefId,
StatusDate = requestDetails.request.rc.StatusDate,
StatusId = requestDetails.request.rc.StatusId,
Reference = requestDetails.request.ri.DistributionReference.Value,
Event = requestDetails.rsc.Event,
CreatedDate = requestDetails.rsc.CreatedDate,
Information = requestDetails.rsc.Information
}).ToList();
Can some please let me know what I am doing wrong?
Many Thanks
Here is the Full query
var query = (from D in
((from tab1 in DbContext.Table1
join tab2 in DbContext.Table2 on tab1.RefId equals tab2.RefId
where (tab1.StatusId == 4 || tab1.StatusId == 6)
&& (tab1.StatusDate >= startDate && tab1.StatusDate <= endDate)
select new
{
RefId = tab1.RefId,
StatusId = tab1.StatusId,
StatusDate = tab1.StatusDate,
Reference = tab2.Reference,
LastChangeId = (from RSC in DbContext.StateChangeTable
where RSC.RefId == tab1.RefId
orderby RSC.ChangeId descending
select RSC.ChangeId).FirstOrDefault()
}))
join RSC in DbContext.StateChangeTable on D.LastChangeId equals RSC.ChangeId
select new StatusDetail
{
RefId = D.RefId,
StatusId = D.StatusId,
StatusDate = D.StatusDate,
Reference = D.Reference,
Event = RSC.Event,
Information = RSC.Information,
CreatedDate = RSC.CreatedDate
}).ToList();
Don't use .Join() you have to use the navigation properties on your entities.

linq to entities left outer join

select SF.FOLDER_NAME,SF.CREATED_DATE,COUNT(st.FOLDER_ID)
from SURVEY_FOLDER SF with (nolock) left outer join SURVEY_TEMPLATE ST with (nolock)
on SF.FOLDER_ID=ST.FOLDER_ID
group by SF.FOLDER_NAME,SF.CREATED_DATE
I need this query in Linq :
I have tried this query,but unable to group by.
My Linq Query :
var data = (from xx in VDC.SURVEY_FOLDER
join yy in VDC.SURVEY_TEMPLATE
on xx.FOLDER_ID equals yy.FOLDER_ID into g
from grt in g.DefaultIfEmpty()
select
new
{
xx.FOLDER_NAME,
xx.CREATED_DATE,
count = g.Count()
}).ToList();
I got the Answer :
var data5 = (from SF in VDC.SURVEY_FOLDER
join ST in VDC.SURVEY_TEMPLATE on new { FOLDER_ID = SF.FOLDER_ID } equals new { FOLDER_ID = (Int64)ST.FOLDER_ID } into ST_join
from ST in ST_join.DefaultIfEmpty()
group new { SF, ST } by new
{
SF.FOLDER_NAME,
SF.CREATED_DATE
} into g
select new
{
g.Key.FOLDER_NAME,
CREATED_DATE = (DateTime?)g.Key.CREATED_DATE,
Column1 = (Int64?)g.Count(p => p.ST.FOLDER_ID != null)
}).ToList();

linq query, convert sql query to linq for VB.net

I am trying to get fields from one table and max(expirationDate) from another table. This is my original linq query:
tanks = (From t In db.Table1 _
Where t.CompanyID = txtCompanyID.Text.Trim() _
Join d In db.Table2 On t.TankID Equals d.TankID
Order By d.ExpireDate Descending
Select t).ToList
that brings back multiple expireDates, I only want the max(expireDate) for each record
The following sql query works, I just need to put it into a linq query
select t1.*,
(Select MAX(Table2.ExpireDate)
from Table2 as t2
where t2.TankID = t1.TankID)
as max_expire_date
from Table1 as t1
where t1.CompanyID = '5467'
order by t1.CargoTankID
Does anybody know how to get this into linq? Thanks
tanks = db.Table1.Where( t => t.CompanyId == txtCompanyID.Text.Trim() )
.Join( db.Table2, t1 => t1.TankID, t2 => t2.TankID, (t1,t2) => new { Company = t1, t2.ExpireDate } )
.GroupBy( t => t.Company, (c,e) => new { Company = c Expiration = e.Max( x => x.ExpireDate ) } )
.ToList();
Best guess at VB
Dim tanks = db.Table1.Where( Function(t) t.CompanyId == txtCompanyID.Text.Trim() ) _
.Join( db.Table2, Function(t1) t1.TankID, Function(t2) t2.TankID, Function(t1,t2) New Thing With { .Company = t1, .ExpireDate = t2.ExpireDate } ) _
.GroupBy( Function(t) t.Company, Function(c,e) New Thing With { .Company = c, .Expiration = e.Max( Function(x) x.ExpireDate ) } ) _
.ToList()

Resources