Sql query to linq convert - sql

Can anyone help me to translate my sql query to linq? I am not so good in linq can anyone help me out with it please .
select
s.UploadFilename ,
a.ID,
isnull(s.Status_id,1) as 'Status_id' ,
a.CaseID,
a.RecordType,
a.ColumnName,
a.FieldName,
a.OldValue,
a.NewValue,
a.ModifiedBy,
A.ModifiedOn,
isnull(u.UserName,'') as 'UserName'
from [dbo].[AuditTrail] as A
left join Case_Status as s
on s.Case_Id=A.CaseID
left join [dbo].[User] as u
on a.ModifiedOn =u.UserID
where A.CaseID=5338

This is not the answer, my query is big, it was not accepting this query as comment.
This query is not returning records :
var AuditTrailFile = (from AT in db.AuditTrails
join ATCS in db.AssnAuditTrailCaseStatus
on new {ID = AT.ID} equals new { ID = (int)(ATCS.AuditTrialID) }
into ATCS_join
from ATCS in ATCS_join.DefaultIfEmpty()
join CS in db.Case_Status on new { Case_StatusId = (int)(ATCS.CaseStatusID) }
equals new { Case_StatusId = CS.Case_StatusId } into CS_join
from CS in CS_join.DefaultIfEmpty()
where
AT.CaseID == CaseID
orderby
AT.ModifiedOn descending
select new
{
ID = (int?)AT.ID,
Case_StatusId = CS.Case_StatusId != null ? CS.Case_StatusId : 1, //Case_StatusId comes for row whose FieldName=Status Else No Case_StatusId
AT.CaseID,
AT.RecordType,
AT.ColumnName,
AT.FieldName,
AT.OldValue,
AT.NewValue,
AT.ModifiedBy,
UserName = AT.User != null ? AT.User.UserName : "",
AT.ModifiedOn,
UploadFilename = CS.UploadFilename
}).ToList();

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?

How do I translate my SQL Query with Having MAX in LINQ?

I'd like to translate this SQL Query in LINQ with EF
SELECT Agts.AgtNum, Agts.AgtLastname, Agts.AgtFirstname, COUNT(Co.CoEnd) FROM [dbo].Agts AS Agts
INNER JOIN [dbo].[Contracts] AS Co ON Agts.AgtNum = Co.AgtNum
GROUP BY Agts.AgtNum, Agts.AgtLastname, Agts.Firstname
HAVING MAX(Co.CoEnd) <= '2020-05-17'
ORDER BY AgtNum asc
I tried that :
public List<AgentToPurge> AgentsToPurge(DateTime datePurge)
{
return (from agent in this.Entities.Agts
join contract in this.Entities.Contracts on agent.AgtNum equals contract.AgtNum
group agent by agent.AgtNum into g
where g.CoEnd <= datePurge
select new AgentToPurge
{
Id = g.Key,
Lastname = g.Key.AgtLastname,
Firstname = g.Key.AgtFirstname,
Contract_Deleted = g.Key.CoEnd.Count()
}).ToList();
}
But the line
where g.CoFin <= datePurge
doesn't work.
I think my "select new" isn't correct either.
Could you help me to solve this ?
Try the following query:
public List<AgentToPurge> AgentsToPurge(DateTime datePurge)
{
return (from agent in this.Entities.Agts
join contract in this.Entities.Contracts on agent.AgtNum equals contract.AgtNum
group contract by new { agent.AgtNum, agent.AgtLastname, agent.AgtFirstname } into g
where g.Max(x => x.CoEnd) <= datePurge
select new AgentToPurge
{
Id = g.Key.AgtNum,
Lastname = g.Key.AgtLastname,
Firstname = g.Key.AgtFirstname,
Contract_Deleted = g.Sum(x => x.CoEnd != null ? 1 : 0)
}).ToList();
}
Note that LINQ query is built from classes and navigation properties and probably you will not need JOIN, if you have properly defined Model.

How to write join query with multiple column - LINQ

I have a situation where two tables should be joined with multiple columns with or condition. Here, I have a sample of sql query but i was not able to convert it into linq query.
select cm.* from Customer cm
inner join #temp tmp
on cm.CustomerCode = tmp.NewNLKNo or cm.OldAcNo = tmp.OldNLKNo
This is how i have write linq query
await (from cm in Context.CustomerMaster
join li in list.PortalCustomerDetailViewModel
on new { OldNLKNo = cm.OldAcNo, NewNLKNo = cm.CustomerCode } equals new { OldNLKNo = li.OldNLKNo, NewNLKNo = li.NewNLKNo }
select new CustomerInfoViewModel
{
CustomerId = cm.Id,
CustomerCode = cm.CustomerCode,
CustomerFullName = cm.CustomerFullName,
OldCustomerCode = cm.OldCustomerCode,
IsCorporateCustomer = cm.IsCorporateCustomer
}).ToListAsync();
But this query doesn't returns as expected. How do I convert this sql query into linq.
Thank you
You didn't tell if list.PortalCustomerDetailViewModel is some information in the database, or in your local process. It seems that this is in your local process, your query will have to transfer it to the database (maybe that is why it is Tmp in your SQL?)
Requirement: give me all properties of a CustomerMaster for all CustomerMasters where exists at least one PortalCustomerDetailViewModel where
customerMaster.CustomerCode == portalCustomerDetailViewModel.NewNLKNo
|| customerMaster.OldAcNo == portalCustomerDetailViewModel.OldNLKNo
You can't use a normal Join, because a Join works with an AND, you want to work with OR
What you could do, is Select all CustomerMasters where there is any PortalCustomerDetailViewModel that fulfills the provided OR:
I only transfer those properties of list.PortalCustomerDetailViewModel to the database that I need to use in the OR expression:
var checkProperties = list.PortalCustomerDetailViewModel
.Select(portalCustomerDetail => new
{
NewNlkNo = portalCustomerDetail.NewNlkNo,
OldNLKNo = portalCustomerDetail.OldNLKNo,
});
var result = dbContext.CustomerMasters.Where(customerMaster =>
checkProperties.Where(checkProperty =>
customerMaster.CustomerCode == checkProperty.NewNLKNo
|| customerMaster.OldAcNo == checkProperty.OldNLKNo)).Any()))
.Select(customerMaster => new CustomerInfoViewModel
{
Id = customerMaster.Id,
Name = customerMaster.Name,
...
});
In words: from each portalCustomerDetail in list.PortalCustomerDetailViewModel, extract the properties NewNKLNo and OldNLKNo.
Then from the table of CustomerMasters, keep only those customerMasters that have at least one portalCustomerDetail with the properties as described in the OR statement.
From every remaining CustomerMasters, create one new CustomerInfoViewModel containing properties ...
select cm.* from Customer cm
inner join #temp tmp
on cm.CustomerCode = tmp.NewNLKNo or cm.OldAcNo = tmp.OldNLKNo
You don't have to use the join syntax. Adding the predicates in a where clause could get the same result. Try to use the following code:
await (from cm in Context.CustomerMaster
from li in list.PortalCustomerDetailViewModel
where cm.CustomerCode == li.NewNLKNo || cm.OldAcNo = li.OldNLKNo
select new CustomerInfoViewModel
{
CustomerId = cm.Id,
CustomerCode = cm.CustomerCode,
CustomerFullName = cm.CustomerFullName,
OldCustomerCode = cm.OldCustomerCode,
IsCorporateCustomer = cm.IsCorporateCustomer
}).ToListAsync();
var result=_db.Customer
.groupjoin(_db.#temp ,jc=>jc.CustomerCode,c=> c.NewNLKNo,(jc,c)=>{jc,c=c.firstordefault()})
.groupjoin(_db.#temp ,jc2=>jc2.OldAcNo,c2=> c2.OldNLKNo,(jc2,c2)=>{jc2,c2=c2.firstordefault()})
.select(x=> new{
//as you want
}).distinct().tolist();

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.

linq to sql , can not solve big sql statement into linq

I am trying very hard but cannot reach my result. I am new to linq. What should be the proper linq query for this sql query. Please help me out of this.
update Teacher set RemainingCredit = RemainingCredit- Course.Credit
from
CourseAssignTeacher
join Course on CourseAssignTeacher.CourseId = Course.Id
join Teacher on CourseAssignTeacher.TeacherId = Teacher.Id
where CourseAssignTeacher.Id = 1
Write a query that selects what you want to update, then use a foreach loop and context.SubmitChanges:
using (DBDataContext db = new DBDataContext())
{
var toUpdate = from cat in db.CourseAssignTeacher
join c in db.Course on cat.CourseId equals c.Id
join t in db.Teacher on cat.TeacherId equals t.Id
where cat.Id = 1
select new { Teacher = t, Course = c, CourseAssignTeacher = cat };
foreach (var x in toUpdate)
{
x.Teacher.RemainingCredit = x.Teacher.RemainingCredit - x.Course.Credit;
}
db.SubmitChanges();
}