Запрос LINQ для значений Group и SUM

У меня SQL Query, как это, и я пытаюсь преобразовать это в код С# с помощью LINQ, но я понятия не имею, как получить значения SUM и Average с помощью LINQ.

SQL-запрос

Select SID, SName, EID, SUM(CAST(EPoints AS Decimal(18, 2)))/COUNT(EFID), EFID, 
SUM(CASE WHEN FValue = 'Y' THEN 1 ELSE 0 END) 'Y', 
SUM(CASE WHEN FValue = 'N' THEN 1 ELSE 0 END) 'N'
from TestTable where ISNULL(FValue, '') != ''
Group By SID, SName, EID, EFID
Order By SID, SName, EID, EFID

Кроме того, я частично конвертировал вышеупомянутый запрос SQL в выражение Linq, но застрял в SUM & Average part, так что, может кто-нибудь сказать мне, как это сделать?

var sortedTable = testTableData.AsEnumerable()
.Where(r => r.Field<string>("FValue") != "")
.GroupBy(r => new
 {
 SID = r.Field<int>("SID"),
 SName = r.Field<string>("SName"),
 EID = r.Field<int>("EID"),
 EFID = r.Field<int>("EFID") 
 })
.OrderBy(g => g.Key.SID)
.ThenBy(g => g.Key.SName)
.ThenBy(g => g.Key.EID)
.ThenBy(g => g.Key.EFID) 
.Select(g => new {
 SID = g.Key.SID,
 SName = g.Key.SName,
 EID = g.Key.EID,
 EFID = g.Key.EFID 
});
</int></int></string></int></string>
3 ответа

Его работа сейчас... Пожалуйста, см. Ниже код, который я использовал:

var sortedTable = testTableData.AsEnumerable()
.Where(r => r.Field<string>("FValue") != "")
.GroupBy(r => new
 {
 SID = r.Field<int>("SID"),
 SName = r.Field<string>("SName"),
 EID = r.Field<int>("EID"),
 EFID = r.Field<int>("EFID") 
 })
.OrderBy(g => g.Key.SID)
.ThenBy(g => g.Key.SName)
.ThenBy(g => g.Key.EID)
.ThenBy(g => g.Key.EFID)
.Select(g => new {
 SID = g.Key.SID,
 SName = g.Key.SName,
 EID = g.Key.EID,
 EFID = g.Key.EFID, 
 Avg = g.Average(x => decimal.Parse(x.Field<string>("EPoints"))),
 YesCount = g.Sum(x => x.Field<string>("FValue") == "Y" ? 1 : 0),
 NoCount = g.Sum(x => x.Field<string>("FValue") == "N" ? 1 : 0)
 });
</string></string></string></int></int></string></int></string>


В вашей части .select вы можете использовать встроенные агрегированные функции linq Average и Sum для выполнения ваших необходимых агрегаций, не уверен, что ниже компилируется, однако он должен логически обслуживать ваши потребности:

.Select(g => new {
 SID = g.Key.SID,
 SName = g.Key.SName,
 EID = g.Key.EID,
 EFID = g.Key.EFID,
 EpointsAverage = g.Average(x => x.EPoints),
 YSum = g.Sum(x => (x.FValue == 'Y' ? 1 : 0)),
 NSum = g.Sum(x => (x.FValue == 'N' ? 1 : 0))
 });

Дайте мне знать, как это происходит, и если есть какие-либо проблемы, чтобы обновить мой ответ соответственно


Здесь вам нужно использовать агрегированные функции, предусмотренные в инфраструктуре Entity, чтобы получить ваш результат как ::

var sortedTable = testTableData.AsEnumerable()
 .Where(r => r.EFValue!=null && r.EFValue!= "")
 .GroupBy(r => new
 {
 SID = r.SID,
 SName = r.SName,
 EID = r.EID,
 EFID = r.EFID 
 })
 .OrderBy(g => g.Key.SID)
 .ThenBy(g => g.Key.SName)
 .ThenBy(g => g.Key.EID)
 .ThenBy(g => g.Key.EFID) 

 .Select(g => new {
 SID = g.Key.SID,
 SName = g.Key.SName,
 EID = g.Key.EID,
 EFID = g.Key.EFID,

 Avg=g.Average(x=>x.EPoints),
 Y=g.Where(x=>x.FValue=="Y").Sum(x=>x.FValue),
 N=g.Where(x=>x.FValue=="N").Sum(x=>x.FValue)
 });

licensed under cc by-sa 3.0 with attribution.