Query syntax in entity framework - sql

I'm doing a query (see below), but I do not know how to retrieve all data from a select.
var model = new dbContext();
var query = from mp in model.matiere_premiere join req in (from stk in model.stock_mp
join ms in model.matiere_premiere
on stk.matiere_premiere_code equals
ms.code
where stk.date <= DateTime.Today
orderby stk.date descending
select new new { stk.qte, stk.matiere_premiere_code })
on mp.code equals req.matiere_premiere_code
group mp by new { mp.code } into grp
orderby grp.Key
select new
{
grp.Key,
grp.First().designation,
grp.Last().frns
};
The equivalent sql query is:
SELECT matiere_premiere.code,matiere_premiere.designation,
"matiere_premiere.unite, matiere_premiere.frns ,IF(ISNULL(REQ.qte), '0.00', REQ.qte) AS qte
FROM matiere_premiere LEFT JOIN (SELECT qte,matiere_premiere_code FROM stock_mp
JOIN matiere_premiere ON matiere_premiere.code = matiere_premiere_code
WHERE DATE <= CURRENT_DATE() ORDER BY DATE DESC)
AS REQ ON REQ.matiere_premiere_code = matiere_premiere.code
GROUP BY matiere_premiere.code ORDER BY matiere_premiere.code

it's simple, the group is also an enumerator, so you should return
select grp;
then, for each group, you can do a foreach of the values
foreach(var group in query)
{
Console.WriteLine("Key: " + group.Key);
foreach(var v in group)
{
Console.WriteLine("Value: " + v.Property);
}
}

Related

Convert SQL Query to query in C#

I've currently got the SQL code below:
WITH region_list
AS (SELECT r.StateProvinceRegion,
r.CafeId,
s.Longitude,
s.Latitude,
ROW_NUMBER() OVER(PARTITION BY r.StateProvinceRegion
ORDER BY s.Longitude DESC) AS row_no
FROM CafeAddress r
inner join Restaurant s on s.CafeId = r.CafeId
)
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS ID,
StateProvinceRegion,
Longitude,
Latitude
FROM region_list
WHERE row_no = 1;
How would I go about adding this query? In my method below I've implemented something similar but I don't understand how to add the WITH clause in.
public VersionResponse GetCafeRegion()
{
var regionList = from cafeAddress in _context.CafeAddress
join cafe in _context.Cafe on cafeAddress.CafeId equals cafe.CafeId
select new { cafeAddress.StateProvinceRegion, cafeAddress.CafeId, cafe.Longitude, cafe.Latitude };
return new VersionResponse()
{
Data = regionList
};
}
Try the below code once.
public VersionResponse GetCafeRegion()
{
var CafeAddress = new List<CafeAddress>();
var Cafe = new List<Cafe>();
var regionList = from cafeAddress in _context.CafeAddress
join cafe in _context.Cafe on cafeAddress.CafeId equals cafe.CafeId
group new { cafeAddress.StateProvinceRegion, cafeAddress.CafeId, cafe.Longitude, cafe.Latitude } by cafeAddress.StateProvinceRegion into g
select g;
List<object> finalResult = new List<object>();
int index = 1;
foreach(var gg in regionList)
{
var groupRecord = gg.OrderByDescending(x => x.Longitude).FirstOrDefault();
finalResult.Add(new
{
ID = index++,
groupRecord.StateProvinceRegion,
groupRecord.CafeId,
groupRecord.Latitude,
groupRecord.Longitude
});
}
return new VersionResponse()
{
Data = finalResult
};
}

select some ids from sql in linq

hi I'm using the query below to select studentId and Score from table1 now i want select users that i selected their ids from table2, how i can select it with ids?
i can select users with this query from v in dc.tbl_Students select v but i want select some users that i have their id.
var qBestMan = (from T in (((from tbl_ActPoints in dc.tbl_ActPoints
select new
{
StudentId = (int?)tbl_ActPoints.StudentId,
Score = (int?)tbl_ActPoints.Score
}).Concat(
from tbl_EvaPoints in dc.tbl_EvaPoints
select new
{
StudentId = (int?)tbl_EvaPoints.StudentId,
Score = (int?)tbl_EvaPoints.Score
})))
group T by new
{
T.StudentId
} into g
orderby g.Sum(p => p.Score) descending
select new
{
g.Key.StudentId,
HighScoreUser = g.Sum(p => p.Score)
}).ToArray();
Try something like this:
//qBestMan must be a List, or a IEnumarable and not a Array. Remove the .ToArray() at the end, or substitute it by .ToList()
var Result = from users in dc.tbl_Students
join bestMen in qBestMan on bestMen.StudentId equals users.userid
select new
{
//fields that you want
example = users.example,
other = bestMen.other
};

SQL to LINQ query equivalent

Hello I need to crate linq query from this SQL:
SQL:
select
p.id,
p.Name,
sum(h.Hour)
from
dbo.Hour h
INNER JOIN dbo.ProjectView p ON h.ProjectId = p.Id
WHERE
h.PeopleId = 7999
group by
p.Name, p.Id
LINQ: I tried this but it is not the same:
var query = from hours in _hourRepository.GetAll()
join proj in _projectRepository.GetAll() on hours.ProjectId equals proj.Id
where hours.PeopleId == personId
group hours by new { proj.Id, proj.Name, proj.Flag, hours.Hours } into g
select new PopleProjectsSumDto
{
Id = g.Key.Id,
Name = g.Key.Name,
Flag = g.Key.Flag,
Hours = g.Sum(h => h.Hours)
};
OK i find solution by removing hours from group:
LINQ:
var query = from hours in _hourRepository.GetAll()
join proj in _projectRepository.GetAll() on hours.ProjectId equals proj.Id
where hours.PeopleId == personId
group hours by new { proj.Id, proj.Name, proj.Flag } into g
select new PopleProjectsSumDto
{
Id = g.Key.Id,
Name = g.Key.Name,
Flag = g.Key.Flag,
Hours = g.Sum(h => h.Hours)
};

Join Subquery result in Linq

I am posting one more doubt of mine:
Is there a way by which we can use the result of one query and then join the same further just like we do in SQL:
SELECT Applications.* , ApplicationFees.ApplicationNo, ApplicationFees.AccountFundDate1,ApplicationFees.AccountFundDate2 ,ApplicationFees.AccountFundDate3 , ApplicationFees.AccountCloseDate1, ApplicationFees.AccountCloseDate2,ApplicationFees.AccountCloseDate3,
isnull(SUBQRY11.AMNT ,0) as SCMSFEE1R,
isnull(SUBQRY12.AMNT,0) as SCMSFEE2R,
Left Join
(
SELECT ApplicationNo,COUNT(ApplicationNo) AS CNT, SUM(Amount) as AMNT
FROM Payments where (FEETYPE=1 AND FeePosition=1) and (FeeDate>='2011-01-01')
and (FeeDate<='2012-01-01')
GROUP BY ApplicationNo
)SUBQRY11
ON ApplicationFees.ApplicationNo= SUBQRY11.ApplicationNo
Left Join
(
SELECT ApplicationNo,COUNT(ApplicationNo) AS CNT2, SUM(Amount) as AMNT
FROM Payments where (FEETYPE=1 AND FeePosition=2) and (FeeDate>='2011-01-01')
and (FeeDate<='2012-01-01')
GROUP BY ApplicationNo )SUBQRY12 ON ApplicationFees.ApplicationNo=SUBQRY12.ApplicationNo
I want to avoid the same in foreach of the query as that will be quite time consuming.
Yes, you can join sub queries. Like this:
var query = from f in db.ApplicationFees
join sub in (from p in db.Payments
where p.Type == 1 && p.Position == 1 &&
p.Date >= fromDate && p.Date <= toDate
group p by p.ApplicationNo into g
select new {
ApplicationNo = g.Key,
CNT = g.Count(),
AMNT = g.Sum(x => x.Amount)
})
on f.ApplicationNo equals sub.ApplicationNo into feePayments
select new { Fee = f, Payments = feePayments };
But writing it in single query is not very maintainable. Consider to compose your query from sub-queries defined separately:
var payments = from p in db.Payments
where p.Type == 1 && p.Position == 1 &&
p.Date >= fromDate && p.Date <= toDate
group p by p.ApplicationNo into g
select new {
ApplicationNo = g.Key,
CNT = g.Count(),
AMNT = g.Sum(x => x.Amount)
};
var query = from f in db.ApplicationFees
join p in payments
on f.ApplicationNo equals p.ApplicationNo into feePayments
select new { Fee = f, Payments = feePayments };

LINQ Right Outer Join Problem

I am writing a right outer join query in SQL Server 2005 and it's working fine, but I am not able to convert it to LINQ.
Here is my query:
select b.number, COUNT(*) AS [AudioCount] from audios a
right join months b on DATEPART(Month, a.[RecordedDate]) = b.number
group by number
Please help me convert it to LINQ.
Thanks & Regards,
Anil Saklania
EDIT: Corrected query.
Depending on what you are looking for I have inverted it to be a left join but it is a left join from months to audio. This will enable you to return a count of zero when a month has no audio recordings. Used paolo's original testing data to test this out.
var audioMonths = from month in ListOfMonths
join audio in ListOfAudios on
month.number equals audio.RecordedDate.Month into audioLeftJoin
from audio in audioLeftJoin.DefaultIfEmpty()
select new
{
Month = month.number,
AudioId = audio != null ? audio.someProperty : null //Need some property on the audio object to see if it exists
};
var monthAudioCount = from audioMonth in audioMonths
group audioMonth by audioMonth.Month into grouping
select new
{
Month = grouping.Key,
AudioCount = grouping.Count(audioMonth => audioMonth.AudioId != null)
};
First, some notes from book: LINQ Pocket Reference by J. & B. Albahari:
1. Using an extra from translates to a SelectMany.
2. An into clause translates to a GroupJoin when it appears directly after a join clause.
Both of the excellent solutions above, by Mike and by Paolo, utilize a second, extra from clause in the query because that translates to a SelectMany.
With SelectMany, a “sequence of sequences” ( a sequence of audio sequences ) is converted into a single flat collection result set. Then, to count the audios, that single flat output collection is, in a second step, grouped according to month. In both solutions above, that is done, and it works OK, but it also necessitates careful checking for nulls.
EXPLOITING THE NATURAL HIERARCHY.
A cleaner alternative way is the use a GroupJoin instead of SelectMany. GroupJoin yields a hierarchical result set, rather than the flat result set of SelectMany. The hierarchical result set needs no grouping, of course, so we eliminate the second step.
Best of all, by utilizing the hierarchical result set of GroupJoin, we don’t have to check for nulls.
Thus we achieve another clean left outer join by this code, and borrowing Paolo's data:
static void Main(string[] args)
{
var ListOfAudios = new List<Audio>() {
new Audio() { someProperty = "test", RecordedDate = new DateTime(2011, 01, 01) },
new Audio() { someProperty = "test", RecordedDate = new DateTime(2011, 01, 02) },
new Audio() { someProperty = "test", RecordedDate = new DateTime(2011, 02, 01) },
new Audio() { someProperty = "test", RecordedDate = new DateTime(2011, 02, 02) }
};
var ListOfMonths = new List<Month>() {
new Month() {number=1, someMonthProperty="testMonth"},
new Month() {number=2, someMonthProperty="testMonth"},
new Month() {number=3, someMonthProperty="testMonth"}
};
var q = from month in ListOfMonths
join audio in ListOfAudios on month.number equals audio.RecordedDate.Month
into hierarch
select new
{
MonthNum = month.number,
AudioCnt = hierarch.Count()
};
foreach (var m in q)
{
Console.WriteLine("{0} - {1}", m.MonthNum,m.AudioCnt);
}
Console.ReadLine();
}
As per some of the comments to your question there are probably more straightforward ways to do what you want than translating your query to linq. However, just as an exercise, here's a way to write it:
var res = from audio in ListOfAudios
join month in ListOfMonths
on audio.RecordedDate.Month equals month.number into joinAudioMonth
from j in joinAudioMonth.DefaultIfEmpty()
group j by j.number into g
select new
{
number = g.Key,
cnt = g.Count()
};
EDIT:
the code above does not do a RIGHT JOIN as you requested, here's a revised one based on Mike's answer. This one does not rely on a property of the Audio object (that might be null even if the object itself exists). But I'm being nitpicky, Mike's answer is basically the correct one.
var audioMonths =
from month in ListOfMonths
join audio in ListOfAudios on
month.number equals audio.RecordedDate.Month into monthAudioJoin
from joined in monthAudioJoin.DefaultIfEmpty()
select new
{
Month = month.number,
J = joined
};
var res = from audioMonth in audioMonths
group audioMonth by audioMonth.Month into grouping
select new
{
number = grouping.Key,
cnt = grouping.Count(a => a.J != null)
};
and here's how I tested it:
public class Audio
{
public string someProperty {get; set;}
public DateTime RecordedDate {get; set; }
}
public class Month
{
public string someMonthProperty {get; set;}
public int number {get; set; }
}
public static void Main (string[] args)
{
var ListOfAudios = new List<Audio>() {
new Audio(){someProperty="test", RecordedDate=new DateTime(2011,01,01)},
new Audio(){someProperty="test", RecordedDate=new DateTime(2011,01,02)},
new Audio(){someProperty="test", RecordedDate=new DateTime(2011,02,01)},
new Audio(){someProperty="test", RecordedDate=new DateTime(2011,02,02)}
};
var ListOfMonths = new List<Month>() {
new Month() {number=1, someMonthProperty="testMonth"},
new Month() {number=2, someMonthProperty="testMonth"},
new Month() {number=3, someMonthProperty="testMonth"}
// ...
};
var audioMonths =
from month in ListOfMonths
join audio in ListOfAudios on
month.number equals audio.RecordedDate.Month into monthAudioJoin
from joined in monthAudioJoin.DefaultIfEmpty()
select new
{
Month = month.number,
J = joined
};
var res = from audioMonth in audioMonths
group audioMonth by audioMonth.Month into grouping
select new
{
number = grouping.Key,
cnt = grouping.Count(a => a.J != null)
};
foreach(var r in res)
{
Console.WriteLine("{0} - {1}", r.number, r.cnt);
}