LINQ query to merge multiple rows - c#

I am trying to convert an SQL query that works, to LINQ equivalent.
Here is the query.
SELECT REPORT_NUMBER,
case when count(distinct STATE) > 1 then 'PENDING'
else case when max(STATE) = 'REPORTED' then 'REPORTED'
else 'PENDING' end end status,
max(REPORT_YEAR)
FROM SAMPLE
GROUP BY REPORT_NUMBER
ORDER BY max(REPORT_YEAR) DESC
So far I created LINQ query that needed a help.
var sums = from foo in db.SAMPLEs
group foo by foo.REPORT_NUMBER into groupings
orderby groupings.Key ascending
select new ReportListModel
{
ReportNbr = groupings.Key,
ReportYear = groupings.Max(g => g.REPORT_YEAR),
ReportSt = groupings.Max(g => g.STATE)
};
Using groupings.Max(g => g.STATE) gives me correct amount of records, but obviously gives me incorrect field result.
How can I create case statement as in SQL query?

You can use inline-if operator like so:
var sums = from foo in db.SAMPLEs
group foo by foo.REPORT_NUMBER into groupings
orderby groupings.Key ascending
select new ReportListModel
{
ReportNbr = groupings.Key,
ReportStatus =
groupings.Select(x => x.STATE).Distinct().Count() > 1 ?
"PENDING" : (
groupings.Max(g => g.STATE) == "REPORTED" ?
"REPORTED" : "PENDING"
)
};

Related

Convert SQL query to LINQ or lambda expression in C# and use in EF Core

I have 3 table
Tbl_City , Tbl_GroupCities , Tbl_CtrCar .
I want to convert this SQL query to LINQ or lambda expression in C#
declare #fk_group uniqueidentifier
SELECT #fk_group= FK_Group
FROM dbo.Tbl_User
WHERE UserName='meysam'
SELECT dbo.Tbl_City.ID_City, dbo.Tbl_City.Name_City,COUNT( dbo.Tbl_CtrCar.Cur_year)
FROM dbo.Tbl_City
INNER JOIN dbo.Tbl_CtrCar ON dbo.Tbl_City.ID_City = dbo.Tbl_CtrCar.FK_City
WHERE ID_City IN (SELECT FK_City
FROM dbo.Tbl_GroupCities
WHERE Active=1 AND ID_Group=#fk_group)
GROUP BY ID_City , Name_City
I try it but it's not work
var model = _TblUser.FirstOrDefault(x => x.UserName == "sampleUserName");
var q = _TblGroupCities.Where(x => x.IdGroup == model.FkGroup && x.Active == true);
var sample2 =
(from x in _TblCity
join a in _TblGroupCities on x.IdCity equals a.FkCity
where a.Active == true && a.IdGroup == model.FkGroup
select new
{
x.IdCity,
x.NameCity
}).ToList();
Please take a look here the features you have in your query are not yet implemented. GroupBy and i think also subselects will do an
SELECT * FROM TableName
And in memory it will do the group by or even for each row a new SQL query.
Better to use the RawSql method for this purpose.
But if you realy want to learn LINQ and convert your SQL take a look at LINQPad
This issue is done. I found my problem, I don't Understand use two joins and use group by in Linq
I use this linq for the solution and run
var model = _TblUser.SingleOrDefault(x => x.UserName == type.UserName);
var q = _TblGroupCities.Where(x => x.IdGroup == model.FkGroup && x.Active == true);
tblCityViewModel = new List<MohasebKhodro.ViewModels.TblCityViewModel>();
var sample2 =
(from x in _TblCity
join a in _TblGroupCities on x.IdCity equals a.FkCity
where a.Active == true && a.IdGroup == model.FkGroup
select new
{
x.IdCity,
x.NameCity
}).ToList();
foreach (var item in sample2)
{
var er = _TblCtrCar.Where(x => x.FkCity == item.IdCity).Max(x => x.CurYear);
tblCityViewModel.Add(new MohasebKhodro.ViewModels.TblCityViewModel
{
IdCity = item.IdCity,
NameCity = item.NameCity,
MaxCurrentYear = Convert.ToString(er)
});
}

How to use Linq query Result in OrderBy?

Here i had scenario to get the data in date wise of this month(Present month)
Excepted Result
Date_time sum(collection.amountreceived ) Sum(bank_deposit.depositamount)
1/07/2014 2000 1000
2/07/2014 3000 3000
Schema
bank_deposit
agentid (nvarchar(30))
depositamount (DECIMAL(10,0))
date_time (TIMESTAMP)
collection
customeridn (varchar(30))
amountreceived (DECIMAL(10,0))
date_time (TIMESTAMP)
agentid (nvarchar(30))
Here I used union to get the datetime column data in one column
var unionDateColumn = ((from agent in db.collections select agent.Date_Time)
.Union(from u in db.bank_deposit select u.Date_Time)).ToList();
How can i use this unionDateColumn data for orderby and to get expected output?
Below is query for sum of amount but here my issue is how to
var model = (from coll in db.collections.Where(e => e.AgentID == item.AgentID)
let depositedAmount = db.bank_deposit.Where(d => d.AgentID == item.AgentID ).Sum(c => c.DepositedAmount) == null ? 0
: db.bank_deposit.Where(d => d.AgentID == item.AgentID).Sum(x => x.DepositedAmount)
let collectionAmount = db.collections.Where(c => c.AgentID == item.AgentID).Sum(c => c.AmountReceived) == null ? 0
: db.collections.Where(v => v.AgentID == item.AgentID).Sum(m => m.AmountReceived)
select new GetBalanceAmount
{
DepositedAmount = depositedAmount,
CollectionAmount = collectionAmount
});
I assume you want to order the result by date_time
var result = unoinDateColumn.OrderBy(t=>t.Date_Time).ToList().;
Why FirstOrDefault ? i asume you want every row.
Sajeetharan's example:
var result = unoinDateColumn.OrderBy(t=>t.Date_Time).ToList();
result is the same as "select * from unionDateColumn order by DateTime"
Your example:
model.ToList().OrderByDescending(unoinDateColumn).FirstOrDefault();
is the same as "Select * from model orderby unionDateColumn"
May i ask why you are handling each column seperately? insted of in one large array ?
Handle it in one array, and do like this model.OrderByDescending(x => x.Date_Time);
it will affect the object model and order it like this model = model.sortedBy(model.Date_Time);

"Case" in the order-by statement

Hello I have the following linq statement:
IEnumerable<TabTransaktion> allTransactions
= TabTransaktions1.Union(TabTransaktions2)
.Where(trans => trans.TabVorgang != null).
.OrderBy(tran => tran.TabVorgang.Wirkdatum)
.OrderByDescending(trans2 => trans2.TabVorgang.ID);
But I want the second order by descending when only trans2.TabVorgang.ID equals to 0. So I need a "case" in "order by clause" for LinQ. A LinQ equivalent of something like this:
SELECT BusinessEntityID, SalariedFlag
FROM HumanResources.Employee
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END;
GO
I would appreciate any help.
Assuming SalariedFlag is a bool (in SQL of type bit), the two ordering expressions are exclusively mutual. In other words, the main query can be separated into two disjunctive queries and the final result is the union of them:
IEnumerable<TabTransaktion> mainQuery
= TabTransaktions1.Union(TabTransaktions2)
.Where(trans => trans.TabVorgang != null);
var queryOne = mainQuery.Where(p=>p.SalariedFlag ==1)
.OrderByDescending(tran => tran.BusinessEntityID );
var queryTwo = mainQuery.Where(p=>p.SalariedFlag ==0)
.OrderBy(tran => tran.BusinessEntityID);
var finalResult = queryOne.Union(queryTwo);

different results between Linq and SQL

i don't know why i get different results between this SQL and LINQ
Could you like to tell me why...?
SQL:
select distinct top 50 (id) as d_id
from talbe1
where id<>-1
order by d_id asc;
Linq:
IList<int> myResults =
(from t in dbconn.table1
where t.id != -1
orderby t.id ascending
select t.id
).Distinct().Take(50).ToList();
int callCnt = 0;
foreach (int row in myResults)
{
callCnt++;
Console.WriteLine(callCnt.ToString() + " " + row.ToString() );
}
The SQL get the results i want,
but the Linq result is like :
1 72662
2 84945
3 264577
4 77655
5 71756
6 76899
7 76719
8 77669
9 152211
10 79168
11 72334
12 71399
13 246031
14 80748
15 77715
.......
This is a limitation of LINQ to SQL, where the OrderBy() must occur after the Distinct(), try this:
IList<int> myResults =
(from t in dbconn.table1
where t.id != -1
select t.id
).Distinct().OrderBy(t => t).Take(50).ToList();
The problem is the way that the Distinct() method works. Unfortunately it can (and usually does) change the order of the items in the list. You need to order the list after calling Distinct().
Try this:
IList<int> myResults =
(
from t in dbconn.table1
where t.id != -1
select t.id
).Distinct().OrderBy(i => i).Take(50).ToList();
Try
var myResults = dbconn.Table1.Where(e => e.id != -1).Select(e => e.id).Distinct()
.OrderBy(t => t).Take(50).ToList();

Can you use a CASE statement with OrderBy in an LINQ to Entities query?

I'm wonder if someone can transform the SQL below to a LINQ to Entities query
SELECT Name, IsEmployee, IsQualityNetwork
FROM Person
ORDER BY CASE WHEN IsQualityNetwork = 1 or IsEmployee = 1 THEN 0 ELSE 1 END, Name
I tried using Linq Dynamic but when this code is executed:
var p = ctx.People
.OrderBy("CASE WHEN IsQualityNetwork = 1 or IsEmployee = 1 THEN 0 ELSE 1 END")
.OrderBy(e => e.Name);
I get the exception:
{"No property or field 'CASE' exists in type 'Person'"}
var p = ctx.People.OrderBy(p => (p.IsQualityNetwork == 1 || p.IsEmployee == 1) ? 0 : 1)
.ThenBy(p => p.Name);
Here's a translation of your SQL to LINQ.
var query = from p in ctx.People
let order = p.IsQualityNetwork || p.IsEmployee ? 0 : 1
orderby order, p.Name
select new
{
p.Name,
p.IsEmployee,
p.IsQualityNetwork,
}
I've used the fluent query syntax so I could show you the let keyword. let allows you to declare a range variable that can then be reused in your query, this can be very useful if you've got a conditional that gets used in a lot of places, or if you need to chain multiple conditionals.

Categories