LINQ syntax question - c#

I have this original SQL that I need to rewrite in LINQ :
SELECT
luProfiles.luProfileID,
luProfiles.ProfileName,
NoOfRights = (SELECT Count(pkProfileRightsID) FROM tblProfileRights WHERE fkProfileID = luProfileID)
FROM luProfiles
WHERE luProfiles.ProfileName LIKE ...
I have done most of it in LINQ, but I am not sure how to add the NoOfRights part to my LINQ. This is what I have done so far :
return from p in _database.LuProfiles
where p.ProfileName.ToLower().StartsWith(strProfile.ToLower())
select p;
Can anybody tell me the right syntax to include the NoOfRights part in my LINQ?

from p in _database.LuProfiles
let NoOfRights = (from r in database.tblProfileRights
where r.fkProfileID == p.luProfileID
select r).Count()
where p.ProfileName.ToLower().StartsWith(strProfile.ToLower())
select new
{
p.luProfileID,
p.ProfileName,
NoOfRights
};

If you are using LINQ-to-SQL or EF, and you have an FK set up, you should have a navigational property ProfileRights. Tn that case, you can query this way:
from p in _database.LuProfiles
where p.ProfileName.ToLower().StartsWith(strProfile.ToLower())
select new
{
p.ProfileId,
p.ProfileName,
NoOfRights = p.ProfileRights.Count()
};

I think this would help you out:
from l in luProfiles
where l.ProfileName.Contains(something)
select new
{
l.luProfileID,
l.ProfileName,
noOfRights = tblProfileRights.Count(t => t.fkProfileID == l.luProfileID)
}

I would recommend you to change SQL first to something like this:
SELECT
luProfiles.luProfileID,
luProfiles.ProfileName,
NoOfRights = COUNT(pkProfileRightsID)
FROM luProfiles
LEFT JOIN tblProfileRights ON fkProfileID = luProfileID
WHERE luProfiles.ProfileName like ...
GROUP BY luProfiles.luProfileID, luProfiles.ProfileName
So this can easily be transformed to LINQ:
return from p in _database.LuProfiles
join o in p.Profiles on p.luProfileID equals o.fkProfileID
group p by new { p.luProfileID, p.ProfileName } into g
select new { g.Key.luProfileID, g.Key.ProfileName , g.Count() }
(not tested, so do it yourself)

Related

LINQ Select newest records that have distinct ForeignKeyId column

I have the following SQL query:
SELECT
table1.Id AS EinAusgangId,
table1.Ausgabedatum,
table1.Rueckgabedatum,
table1.WerkzeugId,
cpmWerkzeug.Name
FROM cpmEinAusgang AS table1
INNER JOIN cpmWerkzeug ON table1.WerkzeugId = cpmWerkzeug.Id
WHERE table1.Id = (SELECT MAX(Id) AS Expr1
FROM dbo.cpmEinAusgang
WHERE table1.WerkzeugId = WerkzeugId)
My aim is to convert the whole query into a LINQ statement for further use in a .Net Application. I already converted joined tables to LINQ but is it also possible to use a select in the where clause?
This is what I got so far, which gives me almost the same result as the SQL statement above, but has major errors when the table cpmEinAusgang contains more then one record for one cpmWerkzeug
using (var dbContext = new cpmEntities())
{
var werkzeuge = from w in dbContext.cpmWerkzeug
join e in dbContext.cpmEinAusgang
on w.Id equals e.WerkzeugId
where e.Rueckgabedatum == null
orderby w.Name
select w;
return werkzeuge.ToList();
}
Has anyone an idea how to achieve the above sql in linq?
Thanks for your help. :)
EDIT:solved (see below)
var werkzeugeImUmlauf = from w in dbContext.cpmWerkzeug
join e in dbContext.cpmEinAusgang
on w.Id equals e.WerkzeugId
where e.Id == dbContext.cpmEinAusgang.Where(x => x.WerkzeugId == e.WerkzeugId).Max(x => x.Id) select w;
This is the final solution. As mentioned by Mittal in his answer, it is possible to write a sub-query in LINQ.
Yes, you can write Sub Query in LINQ as well.
var werkzeuge = from w in dbContext.cpmWerkzeug
join e in dbContext.cpmEinAusgang
on w.Id equals e.WerkzeugId
where w.id = (dbContext.cpmEinAusgang.Max(x => x.id)) AND w.WerkzeugId = WerkzeugId

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

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)
});

convert SQL query to Linq

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);

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