I need to convert following SQL into LINQ
select
app.id,
app.name,
app.version,
s.application,
s.analysis,
s.behaviour,
(select count(ia.id)
from appInstalled ia
JOIN deviceUser ud ON ia.device_id = ud.device_id
where ia.app_id = app.id) as deviceCount,
max(alrt.alert_date)
from application app
left join score s on app.app_md5 = s.md5hash
left join alert alrt on app.id = alrt.app_id
where app.name like '%gpsnav%'
group by device;
This is what I've done so far
var appQuery = (from app in entities.applications
join score in entities.scores on app.app_md5 equals score.md5hash into appScore
join alrt in entities.alerts on app.id equals alrt.app_id into appAlerts
from s in appScore.DefaultIfEmpty()
from a in appAlerts.DefaultIfEmpty()
let deviceCount = (from iapp in entities.appInstalled
join ud in entities.deviceUser on iapp.device_id equals ud.device_id
where iapp.id == app.id
select iapp.id).Count()
where string.IsNullOrEmpty(searchTerm) || app.name.ToLower().Contains(searchTerm.ToLower())
select new
{
AppId = app.id,
AppName = app.name,
AppVersion = app.version,
AppScore = s.application,
Analysis = s.analysis,
Behavior = s.behaviour,
Devices = deviceCount,
AlertDate = a.alert_date
});
var grouped = from a in appQuery
group a by new
{
a.AppId,
a.AppName,
a.AppVersion,
a.AppScore,
a.Analysis,
a.Behavior,
a.Devices,
a.AlertDate
} into g
select new
{
g.Key.AppId,
g.Key.AppName,
g.Key.AppVersion,
g.Key.AppScore,
g.Key.Analysis,
g.Key.Behavior,
g.Key.Devices,
AlertDate = g.Max(x=>x.AlertDate)
};
The above LINQ works but the data is incorrect for Device and AlertDate. What I am missing in here? Also I am not getting max of AlertDate while grouping in LINQ.
Related
I am trying to convert a SQL statement to Linq/Entity Framework, and am having a difficult time. Below is the SQL.
SELECT
trust.FName,
trust.MName,
trust.LName
tla.Address,
tma.Address,
at.Descr
FROM CLIENTSSUITS cs
INNER JOIN TRUSTS trust ON trust.SSN = cs.CLIENT
FULL JOIN ADV_TYPES at ON at.CODE = trust.AT
LEFT OUTER JOIN CLIENTADDRESSES tla ON tla.SSN = trust.SSN AND tla.ID = 'L'
LEFT OUTER JOIN CLIENTADDRESSES tma ON tma.SSN = trust.SSN AND tma.ID = 'M'
WHERE cs.PRIMARY = w AND SecondaryRole = x AND cs.ID = y AND cs.Rev = z AND cs.DELETED = 0
GROUP BY trust.FName,
trust.MName,
trust.LName,
tla.Address,
tma.Address,
at.Descr
The FULL JOIN and the GROUP BY seem to be what I'm struggling most with. I've reviewed this SO answer and I understand how to execute a FULL JOIN on its own, but can't figure out how to integrate that into the larger overall query.
TYA for any answers.
Try this
using(var ctx = new Dbcontext())
{
var list = (
from cs in ctx.CLIENTSSUITS
join trust in ctx.TRUSTS on cs.CLIENT equals trust.CLIENT
join at in ctx.ADV_TYPES on at.CODE equals trust.AT into temp from temp.DefaultIfEmpty()
join tla1 in ctx.CLIENTADDRESSES on tla.SSN equals trust.SSN && tla.ID = 'L' into temp2 from subtla1 in temp2.DefaultIfEmpty()
join tla2 in ctx.CLIENTADDRESSES on tla2.SSN equals trust.SSN && tla2.ID = 'M' into temp3 from subtla2 in temp3.DefaultIfEmpty()
where (cs.PRIMARY = w && ?.SecondaryRole = x && cs.ID = y && cs.Rev = z && cs.DELETED = 0)
select new
{
FName = trust.FName,
MName = trust.MName,
LName = trust.LName
LAddress = tla.Address,
MAddress = tma.Address,
Descr = at.Descr
}).ToList();
}
//if the list contains the right result then you can easily group it with this code
var results = list.GroupBy(x => new {
x.FName, x.MName, x.LName, x.LAddress, x.MAddress, Descr
});
I'm trying to write a LINQ for the below query,
Select DIS.iDataItemID, DIS.iDataItemCurrentStatusID, DI.iDataTypeID,
DI.iEmployeeID, DI.iEmployerID, DI.iLinkID, DI.iSystemID, DI.sData,
DI.sEmployerCode, DI.sRecieptID, COunt(*)
from DataItem DI
INNER JOIN DataItemStatus DIS ON DIS.iDataItemID =
DI.iDataItemID
INNER JOIN RefDataItemStatus ON DIS.iDataItemCurrentStatusID
= RefDataItemStatus.iDataItemStatusID
AND DIS.iDataItemCurrentStatusID = 1 AND DI.iDataTypeID = 8
GROUP BY DIS.iDataItemID, DIS.iDataItemCurrentStatusID, DI.iDataTypeID,
DI.iEmployeeID, DI.iEmployerID, DI.iLinkID, DI.iSystemID, DI.sData,
DI.sEmployerCode, DI.sRecieptID
I have written the LINQ as below, Need to know how to use Group by on this,
from dataItem in msaDBContext.DataItem
join dataItemStatus in msaDBContext.DataItemStatus on dataItem.iDataItemID equals dataItemStatus.iDataItemID
join refDataItemStatus in msaDBContext.RefDataItemStatus on dataItemStatus.iDataItemCurrentStatusID equals refDataItemStatus.iDataItemStatusID
where dataItemStatus.iDataItemCurrentStatusID == _processingStatus.iDataItemStatusID && dataItem.iDataTypeID == _dataType.iDataTypeID
select new
{
iDataItemID = dataItem.iDataItemID,
iDataItemCurrentStatusID = dataItemStatus.iDataItemCurrentStatusID,
iDataTypeID = dataItem.iDataTypeID,
iLinkID = dataItem.iLinkID,
biRowVersion = dataItem.biRowVersion,
sData = dataItem.sData,
iEmployeeID = dataItem.iEmployeeID,
iEmployerID = dataItem.iEmployerID,
sEmployerCode = dataItem.sEmployerCode,
iSystemID = dataItem.iSystemID,
sReceiptID = dataItem.sRecieptID
};
I'm trying to rewrite sql query to linq but can't do it myself.
The most problem for me is to get I,II and III aggregated values.
Sql query:
select o.Name,t.TypeID, SUM(e.I),SUM(e.II),SUM(e.III) from Expenditure e
join Finance f on f.FinanceId = e.FinanceId
join FinanceYear fy on fy.FinanceYearId = f.FinanceYearId and fy.StatusId = 1
join Project p on p.ProjectId = fy.ProjectId
join Organization o on o.OrganizationId = p.OrganizationId
join Type t on t.TypeID = p.TypeID
where fy.Year = 2018
group by o.Name,s.TypeID
and what I have done so far is:
var x = (from e in _db.Expenditures
join f in _db.Finances on e.FinanceId equals f.FinanceId
join fy in _db.FinanceYears on f.FinanceYearId equals fy.FinanceYearId and fy.StatusId = 1 // this does not work, cant join on multiple conditions?
join p in _db.Projects on fy.ProjectId equals p.ProjectId
join o in _db.Organizations on p.OrganizationId equals o.OrganizationId
join s in _db.Types on p.TypeId equals s.TypeId
group new { o, s } by new { o.OrganizationId, s.TypeId }
into grp
select new AggModel
{
OrganizationId = grp.Key.OrganizationId,
TypeId = grp.Key.TypeId,
I = ?,
II = ?,
III = ?,
}
);
Try something like this:
group new { e, o, s } by new { o.OrganizationId, s.TypeId }
into grp
select new AggModel
{
OrganizationId = grp.Key.OrganizationId,
TypeId = grp.Key.TypeId,
I = grp.Sum(a => a.e.I),
II = grp.Sum(a => a.e.II),
III = grp.Sum(a => a.e.III),
}
You'll need to adjust the right side of the lambda to navigate to the correct property.
You Need to use the Group by for aggregation methods.
Check the below link for more Knowledge.
How to use aggregate functions in linq with joins?
I am getting duplication meals here
IEnumerable<DTOHotMealsPrice> lst = (from m in this.dbEntity.HOT_MEALS
join ml in this.dbEntity.HOT_MEALS_PRICE on m.MEALSID equals ml.MEALSID into mls
from mls1 in mls.DefaultIfEmpty()
where mls1.HOTID==hotelId
select new DTOHotMealsPrice
{
MEALSID = m.MEALSID,
MEALSNAME = m.MEALSNAME,
CHPRICE = mls1.CHPRICE,
PRICE = mls1.PRICE,
HOTID = mls1.HOTID
}).Distinct().ToList();
I want to list all HOT_MEALS and also join with
HOT_MEALS_PRICE when a mealsid reference on it
When mls1.HOTID==hotelId, this will getting innerjoin results
How could it will a proper result
Two Way solve Solution
Remove Where Case
Add where Case In Join table
Show for Where Case Blow Linq Query
first Query
IEnumerable<DTOHotMealsPrice> lst = (from m in this.dbEntity.HOT_MEALS
join ml in this.dbEntity.HOT_MEALS_PRICE.where(c=>c.HOTID==hotelId) on m.MEALSID equals ml.MEALSID into mls
from mls1 in mls.DefaultIfEmpty()
select new DTOHotMealsPrice
{
MEALSID = m.MEALSID,
MEALSNAME = m.MEALSNAME,
CHPRICE = mls1.CHPRICE,
PRICE = mls1.PRICE,
HOTID = mls1.HOTID
}).Distinct().ToList();
Second is:
IEnumerable<DTOHotMealsPrice> lst = (from m in this.dbEntity.HOT_MEALS
join ml in this.dbEntity.HOT_MEALS_PRICE on m.MEALSID equals ml.MEALSID into mls
from mls1 in mls.where(c=>c.HOTID==hotelId).DefaultIfEmpty()
select new DTOHotMealsPrice
{
MEALSID = m.MEALSID,
MEALSNAME = m.MEALSNAME,
CHPRICE = mls1.CHPRICE,
PRICE = mls1.PRICE,
HOTID = mls1.HOTID
}).Distinct().ToList();
public static IEnumerable<AppCache> GetTopRatedApps(string language,bool isinitialized)
{
List<AppCache> objApps = new List<AppCache>();
objApps = GetAllApps(isinitialized,language).ToList();
List<RatingCache> objRatings = new List<RatingCache>();
objRatings = GetAllRatings();
var query =
from Apps in objApps
join ratings in objRatings
on Apps.AppId equals ratings.AppId where ratings.RatingGiven == 1
select new AppCache();
return query;
}
Stored Procedure:
select o.AppId, count(*) as ItemCount
from App o
inner join Rating od
on o.AppId = od.AppId
where od.RatingGiven = 1
group by o.AppId
Can't figure out how to get the item count from the list.
Not: AppCache is equivalent to App
This should be the translation of your stored procedure. If you want to return something else, just modify the select method.
var query = from Apps in objApps
join ratings in objRatings
on Apps.AppId equals ratings.AppId
where ratings.RatingGiven == 1
group Apps by Apps.AppId into g
select new { AppId = g.AppId, ItemCount = g.Count() }