EntityFramework groupby not working as on mysql - mysql

I have the following sql query
SELECT statusId, statusName,sum(durationSeconds)/3600 as duration
FROM status
where date_local >=date
and durationSeconds > 0
group by statusId
order by duration desc;
I'm trying to do the same using EF core.
var result = await context.status
.Where(e => e.ShiftdateLocal >= date && e.Durationseconds > 0)
.Select(e => new LiveStatusProductionViewModel
{ StatusId = e.statusId, StatusName = e.statusName, Duration = e.Durationseconds / 3600 })
//.GroupBy(e => e.Duration)
.OrderByDescending(e => e.Duration)
.ToListAsync();
What am I doing wrong? How do I achieve the same result as on mysql?

You have did only half of work, added GroupBy but not added correct projection.
var result = await context.status
.Where(e => e.ShiftdateLocal >= date && e.Durationseconds > 0)
.GroupBy(e => new { e.statusId, e.statusName })
.Select(g => new LiveStatusProductionViewModel
{
StatusId = g.Key.statusId,
StatusName = g.Key.statusName,
Duration = g.Sum(x => x.Durationseconds / 3600)
})
.OrderByDescending(e => e.Duration)
.ToListAsync();

Related

.net core connect to mysql server

I have a issue here for the connect mysql.
I have a vps that contain mysql server have a database name is 'tuyendungbg'. it's had table and data in there. But when i'm connect and query to select data, that have error for 'Table 'tuyendungbg.Careers' doesn't exist'.
here is my controller :
[HttpGet("/nganh-nghe/{slug?}")]
public IActionResult Index(string slug, [FromQuery(Name =
"p")] int currentPage, int
pageSize)
{
if (!string.IsNullOrEmpty(slug))
{
var career = _context.Careers.FirstOrDefault(x =>
x.Slug.Equals(slug));
if (career != null)
{
ViewBag.CareerName = career.CareerName;
//var qr = _context.Careers.ToList();
var qr = (from p in
_context.CompanyCareers.Where(x => x.CareerId ==
career.ID)
from b in _context.Companies.Where(x =>
x.Id == p.CompanyId)
from i in
_context.IndustrialAreas.Where(x => x.ID ==
b.IndustrialAreaId).DefaultIfEmpty()
select new CompanyModelView()
{
Id = b.Id,
CompanyName = b.CompanyName,
BasicSalary = b.BasicSalary,
Allowance = b.Allowance,
DateCreate = b.DateCreate,
JobTitle = b.JobTitle,
Src = b.Src,
_IndustrialArea = i,
Address = b.Address,
Slug = b.Slug,
WorkTypes = (from tc in
_context.CompanyWorkTypes.Where(x =>
x.CompanyId == b.Id)
from type in
_context.WorkTypes.Where(x => x.Id
==
tc.TypeId)
select type)
}
).OrderByDescending(x => x.DateCreate).ToList();
// var worktype = (from w in
_context.CompanyWorkTypes.Where(x =>
x.CompanyId
== qr.))
var totalCate = qr.Count();
if (pageSize <= 0) pageSize = 10;
int countPages =
(int)Math.Ceiling((double)totalCate / pageSize);
if (currentPage > countPages)
currentPage = countPages;
if (currentPage < 1)
currentPage = 1;
var pagingModel = new PagingModel()
{
countpages = countPages,
currentpage = currentPage,
generateUrl = (pageNumber) =>
Url.Action(nameof(Index), new
{
p = pageNumber,
pageSize = pageSize
})
};
ViewBag.pagingModel = pagingModel;
ViewBag.totalPost = totalCate;
ViewBag.cateIndex = (currentPage - 1) * pageSize;
var companies = qr.Skip((currentPage - 1) *
pageSize)
.Take(pageSize).ToList();
ViewBag.JobCount = companies.Count();
//Set slider menu
var leftSlider = new LeftSliderModel()
{
Areas = new SelectList(_context.Areas,
nameof(Area.ID),
nameof(Area.NameArea)),
Careers = new SelectList(_context.Careers,
nameof(Career.ID),
nameof(Career.CareerName)),
WorkTypes = _context.WorkTypes.ToList(),
Experiences = _context.Experiences.ToList()
};
ViewBag.LeftSlider = leftSlider;
return View(companies);
}
}
return NotFound();
}

How to group by in Entity Framework Core with no repetitive group?

I want to perform a group by in Entity Framework core with no repetitive groups.
Lets suppose I have two columns
Column A Column B
1 1
2 1
2 1
4 5
5 4
If a group by is performed for two columns Entity framework core the result is pretty obvious.
Column A Column B
1 1
2 1
4 5
5 4
But i want to perform a group by which works both ways A->B and B->A hence the result would be
Column A Column B
1 1
2 1
5 4
Any idea how to do that in Entity Framework Core?
My original attempt was to use Union
var user = _context.Transactions
.Where(p => !p.IsDeleted && (p.ReceiverUserId == userId) &&
(p.SenderUserId != null))
.Include(p => p.SenderUser)
.GroupBy(p => p.SenderUserId)
.Select(p => new TempModel { Id = p.FirstOrDefault().SenderUser.Id, User = p.FirstOrDefault().SenderUser, CreatedDate = p.FirstOrDefault().CreatedDate });
var user2 = _context.Transactions
.Where(p => !p.IsDeleted && (p.SenderUserId == userId) &&
(p.ReceiverUserId != null))
.Include(p => p.ReceiverUser)
.GroupBy(p => p.ReceiverUserId)
.Select(p => new TempModel { Id = p.FirstOrDefault().ReceiverUser.Id, User = p.FirstOrDefault().ReceiverUser, CreatedDate = p.FirstOrDefault().CreatedDate});
var finalQuery = user.Union(user2);
var finalQuery2 = finalQuery.GroupBy(p => p.Id);
var finalQuery1 = finalQuery2.OrderByDescending(p => p.FirstOrDefault().CreatedDate);
finalQuery.GroupBy(p => p.Id); <- this line gives error
You should sort these columns by descending: 4-5 => 5-4; 5-4 => 5-4;
5-5 => 5-5 and then group by or distinc by them:
var answer = db.Table.Select(x => new
{
ColumnA = x.ColumnA > x.ColumnB ? x.ColumnA : x.ColumnB,
ColumnB = x.ColumnA > x.ColumnB ? x.ColumnB : x.ColumnA
}).Distinct().ToList();

How do I achieve this in C#

How do I aggregate conditionally in C#
Like in the following vb code:
Dim movement = From item In dbo.VIEWITEMMOVEMENTs
Where item.DATETRANSFERRED.Value.Date = Me.DateTimePicker1.Value.Date
Group By item.DATETRANSFERRED.Value.Date, item.ITEMDESCRIPTION
Into moved = Group, sold = Sum(item.QUANTITYSOLD), [IN] = Sum(If(item.QUANTITY < 0.0, 0.0, item.QUANTITY)), Out = Sum(If(item.QUANTITY > 0, 0, item.QUANTITY))
Select ITEMDESCRIPTION, sold, [IN], Out Order By ITEMDESCRIPTION Ascending
Me.DataGridView1.DataSource = movement
var result = (
from item in dbo.VIEWITEMMOVEMENTs
where item.DATETRANSFERRED.Value.Date == this.DateTimePicker1.Value.Date
group item by new { item.DATETRANSFERRED.Value.Date, item.ITEMDESCRIPTION }
into g
select new
{
g.Key.ITEMDESCRIPTION,
sold = g.Sum(x => x.QUANTITYSOLD),
IN = g.Sum(x => (x.QUANTITY <0 ? 0 : x.QUANTITY)),
Out = g.Sum(x => (x.QUANTITY > 0 ? 0 : x.QUANTITY))
}
).OrderBy(d => d.ITEMDESCRIPTION);
if you are trying to convert that snippet of code. you could use the converters like
VB to C#
Hope this helps.

EF 4.1 - code first - query no longer works

I moved from using an edmx file to code first. The following query is no longer working (it's basically a group by with limit 1) :
(from sc in dbContext.student_courses
where
sc.student_id == student.id
&& sc.course_id == course.id
&& sc.complete_flag == 1
group sc by new
{
sc.complete_flag,
sc.direct_to_test_flag,
sc.dept_purchase_flag,
sc.issue_ce_flag,
sc.unlimited_purchase_flag,
sc.survey_taken
}
into scgroup
select new StudentCourseDetails
{
completeVideo = scgroup.Max(x => x.complete_flag),
directToTest = scgroup.Max(x => x.direct_to_test_flag),
isDepartmentPurchase = scgroup.Max(x => x.dept_purchase_flag),
issueCE = scgroup.Max(x => x.issue_ce_flag),
isUnlimitedPurchase = scgroup.Max(x => x.unlimited_purchase_flag),
surveyTaken = scgroup.Max(x => x.survey_taken)
}).FirstOrDefault();
The resulting sql :
SELECT `Limit1`.`complete_flag`,
`Limit1`.`C1`,
`Limit1`.`C2`,
`Limit1`.`C3`,
`Limit1`.`C4`,
`Limit1`.`C5`,
`Limit1`.`C6`
FROM (SELECT `GroupBy1`.`A1` AS `C1`,
`GroupBy1`.`A2` AS `C2`,
`GroupBy1`.`A3` AS `C3`,
`GroupBy1`.`A4` AS `C4`,
`GroupBy1`.`A5` AS `C5`,
`GroupBy1`.`A6` AS `C6`,
`GroupBy1`.`K1` AS `complete_flag`
FROM (SELECT Max(`complete_flag`) AS `A1`,
Max(`direct_to_test_flag`) AS `A2`,
Max(`dept_purchase_flag`) AS `A3`,
Max(`issue_ce_flag`) AS `A4`,
Max(`unlimited_purchase_flag`) AS `A5`,
Max(`survey_taken`) AS `A6`
FROM `student_courses` AS `Extent1`
WHERE ((`Extent1`.`student_id` = 3885 /* #p__linq__0 */)
AND (`Extent1`.`course_id` = 606 /* #p__linq__1 */))
AND (1 = `Extent1`.`complete_flag`)
GROUP BY `Extent1`.`complete_flag`,
`Extent1`.`dept_purchase_flag`,
`Extent1`.`direct_to_test_flag`,
`Extent1`.`issue_ce_flag`,
`Extent1`.`survey_taken`,
`Extent1`.`unlimited_purchase_flag`) AS `GroupBy1`
LIMIT 1) AS `Limit1`
The problem is that when it adds the limit 1, it also adds an extra column :
GroupBy1.K1 AS complete_flag - which doesn't exist.
Any thoughts ?

LINQ to SQL refactoring foreach help

Can this be refactored into one LINQ statement? I feel like it can be but can't wrap my head around it. The mishmash of extension methods and LINQ just looks ugly to me.
(db is a DataContext.)
void AddToSeries(Series series, DateTime date)
{
foreach (var date in db.Ad.Select(ad => ad.DateTime.Date).Distinct())
{
var phraseCount = (from pc in db.PhraseCount
where pc.DateTime.Date == date
select pc.Count).SingleOrDefault();
var adCount = db.Ad.Where(ad => ad.DateTime.Date == date).Count();
series.Add(new KeyValuePair<DateTime, double>(date, adCount));
}
}
First refactor to consistent style.
void AddToSeries(Series series, DateTime date)
{
var dates = db.Ad
.Select(ad => ad.DateTime.Date)
.Distinct();
foreach (DateTime date in dates)
{
var phraseCount = db.PhraseCount
.Where(pc => pc.DateTime.Date == date)
.Select(pc => pc.Count)
.SingleOrDefault();
var adCount = db.Ad
.Where(ad => ad.DateTime.Date == date)
.Count();
series.Add(new KeyValuePair<DateTime, double>(date, adCount));
}
}
Aha:
phraseCount is not used
key is a date, value is a count
multiple database trips is no fun
date parameter for this method is blocked by the foreach variable
Now we can refactor:
void AddToSeries(Series series, DateTime date)
{
var pairs = db.Ad
.GroupBy(ad => ad.DateTime.Date)
.Select(g => new {key = g.Key, theCount = g.Count()});
foreach (var x in pairs)
{
series.Add(new KeyValuePair<DateTime, double>(x.key, x.theCount));
}
}