Change to linq left join query - sql

SELECT I.*, SI.SupplierID FROM item I
LEFT JOIN SupplierItem SI ON I.ItemID = SI.ItemID AND I.Price = SI.Price
WHERE I.CurrentQty <= I.ReorderLevel and SI.SupplierID = 'AlPA'
how can i change that sql query to Linq Query.

The below query will convert your Sql query to Linq query
var data =
from row in db.item
join row1 in db.SupplierItem
on new { ID= row.ItemID , Price = row.Price }
equals new { ID= row1.ItemID , Price = row1.Price } into joinedData
from row2 in joinedData.DefaultIfEmpty()
where row.CurrentQty <= row.ReorderLevel && row2.SupplierID == "AlPA"
select new {
item = row,
SupplierID = row2.SupplierID
};

Related

SQL Statement with inner join to LINQ

I need to convert my SQL statement to LINQ.
SELECT
dbo.Transactions.TypeRefID,
dbo.TransactionItems.ItemRefID,
SUM(dbo.TransactionItems.Quantity) AS Qty
FROM
dbo.TransactionItems
LEFT OUTER JOIN
dbo.Transactions ON dbo.TransactionItems.TransactionRefID = dbo.Transactions.TransactionID
GROUP BY
dbo.Transactions.TypeRefID, dbo.TransactionItems.ItemRefID
HAVING
(dbo.Transactions.TypeRefID = 1)
AND (dbo.TransactionItems.ItemRefID = 5)
I tried converting the above statement into LINQ and this is what I've done.
var query = from t in db.Transaction
join i in db.TransactionItem on t.TransactionID equals i.TransactionRefID
where t.TypeRefID == 1 && i.ItemRefID == 5
group i by new
{
t.TypeRefID,
i.ItemRefID
} into g
select new
{
TypeRefID = g.Key.TypeRefID,
ItemRefID = g.Key.ItemRefID,
Quantity = g.Sum(q => q.Quantity)
};
When I run my code I get error "System.Linq.Queryable.FirstOrDefault(...) returned null"
I'm using it like this
if (query != null)
string qty = query.FirstOrDefault().Quantity.ToString();
The error is called on "query.FirstOrDefault().Quantity.ToString()"
How to avoid this error?

hat is the LINQ equivalent for the following SQL query?

T-SQL query:
SELECT T1.ID,
T1.UserId,
T1.ServerId,
T1.DiskId,
T1.Date_ PreviousDate_,
T1.Row,
MIN(T2.Date_) AS Date_,
DATEDIFF(MINUTE, T1.Date_, MIN(T2.Date_)) AS MinutesDiff
FROM IesLogs T1
LEFT JOIN IesLogs T2
ON T1.DiskId = T2.DiskId
where T1.DiskId = 2 AND T2.Date_ > T1.Date_ AND T1.Row = T2.Row
GROUP BY T1.ID,T1.UserId, T1.ServerId, T1.DiskId, T1.Date_, T1.[Row]
ORDER BY T1.DiskId, T1.[Row], T1.Id
I am getting more data than I expected.
var result = (
from i in context.IesLogs
join i2 in context.IesLogs
on i.DiskId equals diskId into i2left
from i3 in i2left.DefaultIfEmpty()
where
i.UserId == userId
&& i3.Date > i.Date
&& i.Row == i3.Row
group i3 by new {i.Id, i.ServerId,i.DiskId, i.Row, PreviousDate = i.Date, i3.Date} into logs
orderby logs.Key.DiskId, logs.Key.Row,logs.Key.Id ascending
select new IesLogStatisticsDto
{
Id = logs.Key.Id,
ServerId = logs.Key.ServerId,
DiskId = logs.Key.DiskId,
PreviousDate = logs.Key.PreviousDate,
Date = logs.Min(x => x.Date),
Row = logs.Key.Row,
DateDiff = Convert.ToInt32((logs.Min(x => x.Date) - logs.Key.PreviousDate).TotalMinutes)
}).ToList();
I'm getting 12 when I should be getting 6 data. How Can I solve this ?
I think the reason why I'm getting a lot of data is the(i3.Date > i.Date) in the code blog above but I have to implement this line.
Your LINQ query has wrong grouping. You have to remove i3.Date from grouping key.
A little bit refactored:
var query =
from i in context.IesLogs
join i2 in context.IesLogs
on i.DiskId equals diskId into i2left
from i2 in i2left.DefaultIfEmpty()
where
i.UserId == userId
&& i2.Date > i.Date
&& i.Row == i2.Row
group i2 by new {i.Id, i.ServerId, i.DiskId, i.Row, PreviousDate = i.Date} into logs
orderby logs.Key.DiskId, logs.Key.Row, logs.Key.Id ascending
select new IesLogStatisticsDto
{
Id = logs.Key.Id,
ServerId = logs.Key.ServerId,
DiskId = logs.Key.DiskId,
PreviousDate = logs.Key.PreviousDate,
Date = logs.Min(x => x.Date),
Row = logs.Key.Row,
DateDiff = Convert.ToInt32((logs.Min(x => x.Date) - logs.Key.PreviousDate).TotalMinutes)
};

I need to transform a SQL query with inner joins to Linq in Entity Framework

I am very new to translating queries to entity, I don't know how to replace that query into linq in my code
select
brules.rule_description, brules.user_story_number,
so.source_name,
count(dlog.row_id) as error_count,
cast(execution_date as date) as execution_date
from
br.lk_business_rules brules
inner join
br.business_rules_detailed_log dlog on dlog.user_story_number = brules.user_story_number
inner join
br.lk_business_rules_source so on so.source_id = source_id_fk
where
brules.status_id_fk = 3
group by
brules.rule_description, brules.user_story_number,
so.source_name, cast(execution_date as date)
order by
brules.rule_description
i tried this:
var query = from br in _context.Lk_business_rules
join detLog in _context.Business_rules_detailed_log
on br.User_story_number equals detLog.User_story_number
join source in _context.Lk_business_rules_source
on detLog.Source_id equals source.Source_id
where br.Status_id_fk == 3
select new
{
Business_rule_description = br.Rule_description,
Business_rule_storynumber = br.User_story_number,
Source = source.Source_name,
Error_count = detLog.Row_id.Count,
Date = detLog.Execution_date
};
but not succed

Linq to SQL - Query with multiple joins, sum, grouping, having

I have the following query that I would like to translate to linq.
SELECT
SUM(Credits.CreditAmount)
,Transactions.Id
,Person.FullName
,Person.Id
FROM
Person
JOIN
Transactions
ON Person.AccountId = Transactions.AccountId
JOIN Credits
ON Transactions.Id = Credits.TransactionId
WHERE
Person.Type = 'AccountHolder'
AND Person.Status = 'Active'
AND Transactions.CancelledDate IS NULL
AND Credits.CancelledDate IS NULL
GROUP BY Transactions.AccountId, Person.FullName, Person.Id
HAVING SUM(Credits.CreditAmount) > 20
This is what I came up with. It's an absolute pig... The SQL it generates must be awful.
var query = from p in Person
join t in Transactions
on p.AccountId equalas t.AccountId
join c in Credits
on t.TransactionId = c.TransactionId
where p.Status == "Active" &&
p.Type = "AccountHolder" &&
t.CancelledDate == null &&
c.CancelledDate == null
group new { c.CreditAmount, t.AccountId, p.FullName, p.Id } by new { t.AccountId, p.FullName, p.SSN } into grp
let sumC = grp.Select(x => x.CreditAmount).Sum()
select new
{
TotalCredit = sumC,
AccountId = grp.Key.AccountId,
FullName = grp.Key.FullName,
Id = grp.Key.Id
};
query.Where(p => p.TotalServiceCredit > 20);
The SQL query runs in approximately 3 seconds but I have yet to find the patience to let the Linq query finish. I was wondering if there is something different I should be doing to accomplish this "group, sum, having" query I'm trying to write? Is there something I can do to help Linq generate more performat SQL?
UPDATE
Turns out sgmoore had the right idea. The key to the performance issue was in his answer.
The difference between this
let sumC = grp.Select(x => x.CreditAmount).Sum()
and this
TotalCredit = grp.Sum(x => x.CreditAmount)
was the difference between a query that finishes and one that does not.
See my revised LINQ query below which completes in about the same time as the SQL (5.3 seconds for SQL vs 5.6 seconds for LINQ).
var query = from p in Person
join t in Transactions
on p.AccountId equalas t.AccountId
join c in Credits
on t.TransactionId = c.TransactionId
where p.Status == "Active" &&
p.Type = "AccountHolder" &&
t.CancelledDate == null &&
c.CancelledDate == null
group new { c.CreditAmount, t.AccountId, p.FullName, p.Id } by new { t.AccountId, p.FullName, p.SSN } into grp
select new
{
TotalCredit = grp.Sum(x => x.CreditAmount),
AccountId = grp.Key.AccountId,
FullName = grp.Key.FullName,
Id = grp.Key.Id
};
query.Where(p => p.TotalServiceCredit > 20);
Thanks for all your help!
I don't disagree with WEI_DBA's comment but if you need to do this, then you might find it easier to break this into several queries, eg
var query1 = from p in Person
join t in Transactions on p.AccountId equals t.AccountId
join c in Credits on t.TransactionId equals c.TransactionId
where p.Status == "Active" &&
p.Type = "AccountHolder" &&
t.CancelledDate == null &&
c.CancelledDate == null
select new { c.CreditAmount, t.AccountID, p.FullName, p.Id};
var query2 = (from p in query1
group p by new { p.AccountId, p.FullName, p.Id } into grp
select new
{
TotalCredit = grp.Sum(x => x.CreditAmount),
AccountId = grp.Key.AccountId,
FullName = grp.Key.FullName,
Id = grp.Key.Id
};
var query3 = (from p in query2 where p.TotalCredit > 20 select p);
Then you can let LINQ combine this into one sql command.
As always, it is a good idea to check and verify the actual TSQL generated.

converting SQL join with group by and MAX to Linq

I have Created following query in sql but i am not able to find out how to implement StatusAndTrackingNotes table join in my linq:
SELECT *
FROM [Application] APP
join User USR on APP.ApplicationId = USR.UserApplicationId
join
(Select MAX(TrackingDate) as MaxDateTD,TrackingApplicationId
From StatusAndTrackingNotes
where TrackingLoanType = 1 and ((TrackingStatusCode <= 52 and TrackingStatusCode >= 50) or TrackingStatusCode = 62)
group by TrackingApplicationId) MTND on APP.ApplicationId = MTND.TrackingApplicationId
join Details DTL on APP.ApplicationId = DTL.ApplicationId
join ApplicationFees AF on APP.ApplicationId = AF.ApplicationId
where APP.LatestStatus = 'F' and DTL.Type = 1 and DTL.FundingDate >= '2011-06-01' and DTL.FundingDate <= '2013-06-30'
and AF.FirstRefPaidDate is not null
Kindly help me with the syntax.First i was using using simple query with joins and then
([Linq Query]).GroupBy(i => i.TrackingApplicationId).Select(g => g.OrderByDescending(c => c.TrackingDate).FirstOrDefault());
but it doesnt return any result. Kindly help.
Thanks in advance
I would solve it by creating StatusAndTrackingNotes as separate query and join and group it to the "main query". I.e:
var trackingQuery =
from t in statusAndTrackingNotes
where t.TrackingLoanType == 1 && (t.TrackingStatusCode <= 52 && t.TrackingStatusCode >=50) || t.TrackingStatusCode == 62
group t by t.TrackingApplicationId into trackings
select new
{
TrackingApplicationId = trackings.Key,
MaxDate = trackings.Max(t => t.TrackingDate)
};
var appQuery =
from app in Application
join t in trackingQuery on app.ApplicationId equals t.TrackingApplicationId
/* other joins here */
select new
{
app,
t.MaxDate,
};