convert SQL query to Linq - c#

Could somebody assist me in converting a sql query into LINQ ? I well understand SQL queries, but I am a novice in Linq. Thank you so much for help me.
SELECT
subConsulta."NitIps",
subConsulta."NumFactura",
COUNT(*)
FROM
(SELECT
DISTINCT acf."NitIps",
acf."NumFactura",
acf."TipoSoporte"
FROM
"t_ArchivoCentralFacturacion" AS acf
inner join "t_TRCompartaTiposDocumentalesAC" AS ctd
on
acf."TipoSoporte"= ctd."Id"
GROUP BY
acf."NitIps",
acf."NumFactura",
acf."TipoSoporte")as subConsulta
GROUP BY
subConsulta."NitIps",
subConsulta."NumFactura"
ORDER BY
subConsulta."NitIps",
subConsulta."NumFactura"

If you map your tables to entities it looks like follow:
var first = from archivoCentralFacturacion in ArchivoCentralFacturacions
group archivoCentralFacturacion by new {
c.NitIps,
c.NumFactura,
c.TipoSoporte
} into subConsulta
select subConsulta;
var result = (from f in first
group f by new {
f.NitIps,
f.NumFactura
} into r
select new {
NitIps = r.NitIps,
NumFactura = r.NumFactura,
ResultCount = r.Count()
}).OrderBy(x => x.NitIps).ThenBy(x => x.NumFactura);

Related

How To Translate SQL Inner Join, Groupby Into Linq?

Here I have SQL query, now I am trying to translate it into linq but don't have any idea how to do it and got stuck in getting ChapterId from ChapterQuestion table.
Any help with translation will be grate.
Thank you
Below is my sql query
SELECT CQ.ChapterId,CQS.SetNumber,count(distinct CQ.ChapterQuestionId) as questioncount FROM
[dbo].[ChapterQuestion] AS CQ
JOIN [dbo].[ChapterQuestionSet] AS CQS ON CQ.ChapterQuestionSetId = CQS.ChapterQuestionSetId
WHERE CQ.ChapterId = 1 group by CQS.SetNumber,CQ.ChapterId
Below is my linq
var list = (from CQS in uow.Repository<ChapterQuestionSet>().GetAll().ToList()
join CQ in uow.Repository<ChapterQuestion>().FindBy(x => x.ChapterId == chapterId).ToList()
on CQS.ChapterQuestionSetId equals CQ.ChapterQuestionSetId
group CQ by CQS into G1
select new ChapterQuestionSetVM
{
ChapterQuestionSetId = G1.Key.ChapterQuestionSetId,
Count = G1.Count(t => t.ChapterQuestionSetId != null),
QuestionSetNo = $"Question set {G1.Key.SetNumber}",
ChapterId = // how do i get chapterid from ChapterQuestion
}).ToList();
This is corrected query. I hope Repository.GetAll() returns IQueryable?
This query works only with EF Core 5.x
var query =
from CQS in uow.Repository<ChapterQuestionSet>().GetAll()
join CQ in uow.Repository<ChapterQuestion>().GetAll() on CQS.ChapterQuestionSetId equals CQ.ChapterQuestionSetId
where CQ.ChapterId == 1
group CQ by new { CQS.SetNumber, CQ.ChapterId } into G1
select new ChapterQuestionSetVM
{
ChapterId = G1.Key.ChapterId
QuestionSetNo = $"Question set {G1.Key.SetNumber}",
Count = G1.Select(t => t.ChapterQuestionSetId).Distinct().Count(),
};
var list = query.ToList();

Select where IN using LINQ

Hello I'm trying to use IN condition in LINQ.
I have the following query:
select * from unitphotos Where MarketingFileTypeID = 2
AND UnitTypeID in (Select UnitTypeID from unitTypes Where PropertyID = 1)
I think I can't make it in only one LINQ query, so I did this:
var listUnitTypes = (from ut in db.unittypes
where ut.PropertyID == propertyID
select new { ut.UnitTypeID }).ToList();
var getPropertyPhotos = (from up in db.unitphotos
where listUnitTypes.Contains(up.UnitTypeID)
select up).ToList();
However, it gives me a syntax error inside Contains(up.UnitTypeID): "Argument 1: cannot convert from 'int' to 'anonymous type int UnitTypeID'
Does anyone know what I am doing wrong?
Thanks
var getPropertyPhotos = (from up in db.unitphotos
where unittypes.Any(ut => ut.PropertyID == propertyID && ut.UnitTypeId == up.UnitTypeID)
select up).ToList();
I think this should work. Haven't tried it since I don't have the db though so ymmv.
Also, yours should work if instead of select new { ut.UnitTypeID } you just put select ut.UnitTypeID
You have anonymous type here
var listUnitTypes = (from ut in db.unittypes where ut.PropertyID == propertyID select new { ut.UnitTypeID }).ToList();
And then try to use it in Linq To Entity:
var getPropertyPhotos = (from up in db.unitphotos
where listUnitTypes.Contains(up.UnitTypeID)
select up).ToList();
Seems like Linq to Entity won`t know what that type is.
So you can replace
select new { ut.UnitTypeID })
with
select { ut.UnitTypeID })
as #anakic sad before
And then create 1 query by Linq
var listUnitTypes = (from ut in db.unittypes where ut.PropertyID == propertyID select ut.UnitTypeID);
var getPropertyPhotos = (from up in db.unitphotos where listUnitTypes.Contains(up.UnitTypeID) select up).ToList();
By that you force Linq to Sql create complicated query that should be able to handle your problem.
I think that the way that you are approaching the problem forcing a sub-select is going to end up having you going back to the database more than you have to. I don't have an IDE available right now to bang out the correct LINQ syntax, but why not change your approach from thinking in terms of a SQL sub-select to that of a JOIN? Here is the SQL that I would start with and then translate that to LINQ:
SELECT p.*
FROM unitphotos p
INNER JOIN unitTypes u
ON u.UnitTypeID = p.UnitTypeID
AND u.PropertyID = 1
WHERE p.MarketingFileTypeID = 2

SQL query in LINQ to SQL

I am trying to write SQL query in LINQ to SQL but after 4h of trying i gave up.
select B.* from Bid B
join
(
select BidId, max(BidVersion) as maxVersion
from Bid
group by BidId
) X on B.BidId = X.BidId and B.BidVersion = X.maxVersion
i saw some tips on the stackOverflow but they werent helpful.
I am using some VERY bad code like:
List<Bid> bidEntities = new List<Bid>();
var newest = from bid in _dbContext.Bids
group bid by bid.BidId into groups
select new { Id = groups.Key, Vs = groups.Max(b => b.BidVersion) };
foreach (var group in newest)
{
bidEntities.Add(await _dbContext.Bids.Where(b => b.BidId == group.Id && b.BidVersion == group.Vs).SingleOrDefaultAsync());
}
Thank you for any advice.
Something like this should work:
var rows = Bids
.GroupBy(b => b.BidId)
.Select(g => g.OrderByDescending(gg => gg.BidVersion).FirstOrDefault())
With LINQ, it helps sometimes not to think in the 'SQL way', but about what you really want. You want the highest version bid for each BidId

Join 2 table and group 2 field in linq

I have a very simple SQL
SELECT s.shop_code
,SUM(im.amt) sum_amt
,s.cell_no#1 shop_cell
FROM tb_sn_so_wt_mst im
,tb_cm_shop_inf s
WHERE im.shop_code = s.shop_code
GROUP BY s.shop_code, s.cell_no#1)
then i try to code linq
var listResult = from warrantyMaster in listWarrantyMasters2.Records
join shopInfo in listShopInfos
on warrantyMaster.ShopCode equals shopInfo.ShopCode
i don't know group by shop code and cell no and sum atm, any one help me out of this problem
The group by syntax with some examples is explained here group clause (C# Reference) and related links.
Here is the direct translation of your SQL query (of course the field names are just my guess since you didn't provide your classes):
var query = from im in listWarrantyMasters2.Records
join s in listShopInfos
on im.ShopCode equals s.ShopCode
group im by new { s.ShopCode, s.CellNo } into g
select new
{
g.Key.ShopCode,
g.Key.CellNo,
SumAmt = g.Sum(e => e.Amt)
};
You can try this code:
var results = from warrantyMaster in listWarrantyMasters2.Records
from shopInfo in listShopInfos
.Where(mapping => mapping.ShopCode == warrantyMaster.ShopCode )
.select new
{
ShopCode = warrantyMaster.ShopCode,
ATM = listWarrantyMasters2.ATM,
ShellNo = shopInfo.ShellNo
}
.GroupBy(x=> new { x.ShopCode, x.ShellNo })
.Select(x=>
new{
ShopCode = x.Key.ShopCode,
ShellNo = x.Key.ShellNo,
SumATM = x.Sum(item=>item.ATM)
});

LINQ to SQL omit field from results while still including it in the where clause

Basically I'm trying to do this in LINQ to SQL;
SELECT DISTINCT a,b,c FROM table WHERE z=35
I have tried this, (c# code)
(from record in db.table
select new table {
a = record.a,
b = record.b,
c = record.c
}).Where(record => record.z.Equals(35)).Distinct();
But when I remove column z from the table object in that fashion I get the following exception;
Binding error: Member 'table.z' not found in projection.
I can't return field z because it will render my distinct useless. Any help is appreciated, thanks.
Edit:
This is a more comprehensive example that includes the use of PredicateBuilder,
var clause = PredicateBuilder.False<User>();
clause = clause.Or(user => user.z.Equals(35));
foreach (int i in IntegerList) {
int tmp = i;
clause = clause.Or(user => user.a.Equals(tmp));
}
var results = (from u in db.Users
select new User {
a = user.a,
b = user.b,
c = user.c
}).Where(clause).Distinct();
Edit2:
Many thanks to everyone for the comments and answers, this is the solution I ended up with,
var clause = PredicateBuilder.False<User>();
clause = clause.Or(user => user.z.Equals(35));
foreach (int i in IntegerList) {
int tmp = i;
clause = clause.Or(user => user.a.Equals(tmp));
}
var results = (from u in db.Users
select u)
.Where(clause)
.Select(u => new User {
a = user.a,
b = user.b,
c = user.c
}).Distinct();
The ordering of the Where followed by the Select is vital.
problem is there because you where clause is outside linq query and you are applying the where clause on the new anonymous datatype thats y it causing error
Suggest you to change you query like
(from record in db.table
where record.z == 35
select new table {
a = record.a,
b = record.b,
c = record.c
}).Distinct();
Can't you just put the WHERE clause in the LINQ?
(from record in db.table
where record.z == 35
select new table {
a = record.a,
b = record.b,
c = record.c
}).Distinct();
Alternatively, if you absolutely had to have it the way you wrote it, use .Select
.Select(r => new { a = r.a, b=r.b, c=r.c }).Distinct();
As shown here LINQ Select Distinct with Anonymous Types, this method will work since it compares all public properties of anonymous types.
Hopefully this helps, unfortunately I have not much experience with LINQ so my answer is limited in expertise.

Categories

Resources