GroupBy and Select in EF Core - c#

I'm trying to get a list of all unique combinations of make and model and also include the most recent time stamp and the color from the following table:
+-------+---------+-------------------------+--------+
| Make | Model | Last Seen | Color |
+-------+---------+-------------------------+--------+
| Volvo | XC90 | 2022-03-11 13:30:31.623 | Blue |
| Volvo | XC90 | 2022-03-11 14:30:31.623 | Green |
| BMW | M3 | 2022-03-11 15:30:31.623 | Orange |
| Ford | Mustang | 2022-03-11 16:30:31.623 | Red |
+-------+---------+-------------------------+--------+
This query will give me a list of all combinations of make and model and include the latest timestamp, but I don't know how I can also include the Color.
var lastSeen = _context.Cars.GroupBy(o => new {o.Make, o.Model})
.Select(n => new {Make = n.Key.Make, Model = n.Key.Model, Max = n.Max(a => a.LastSeen)})
.ToList();
I'm looking for the following output:
+-------+---------+-------------------------+--------+
| Make | Model | Last Seen | Color |
+-------+---------+-------------------------+--------+
| Volvo | XC90 | 2022-03-11 14:30:31.623 | Green |
| BMW | M3 | 2022-03-11 15:30:31.623 | Orange |
| Ford | Mustang | 2022-03-11 16:30:31.623 | Red |
+-------+---------+-------------------------+--------+
Thanks!

Related

Aggregate multiple columns in DataTable and put result to new DataTable

Hi i have a DataTable with following data formating. I am trying to aggregate in C# on condition. I am a Newbie to Linq.
Profile | Nr | Result|
------------------------
A | 1 | OK |
A | 2 | NOK |
A | 2 | OK |
A | 3 | OK |
A | 4 | OK |
A | 5 | OK |
BB | 1 | OK |
BB | 2 | NOK |
BB | 2 | NOK |
BB | 2 | OK |
BB | 3 | OK |
BB | 4 | OK |
BB | 5 | OK |
I Want to aggregate by first columnt (Profile) and count rows where the Result is OK.
The expected result should be a new DataTable and should look like this.
Profile | Count|
----------------
A | 5 |
BB | 5 |
How can i do this in C# ?

Querying one record of each type between dates

I have a table (attendance) like this
+----+--------------------------+-------+------------+
| id | employeeId | type | date |
+----+--------------------------+-------+------------+
| 0 | alberto | A | 2019-10-01 |
| 1 | alberto | A | 2019-10-02 |
| 2 | alberto | A | 2019-10-03 |
| 3 | pedro | B | 2019-10-01 |
| 4 | pedro | B | 2019-10-02 |
| 5 | pedro | B | 2019-10-03 |
| 6 | juan | A | 2019-10-01 |
| 7 | juan | A | 2019-10-02 |
| 8 | oscar | A | 2019-10-01 |
| 9 | marcelo | B | 2019-10-01 |
| 10 | marcelo | B | 2019-10-02 |
| 11 | marcelo | B | 2019-10-03 |
+----+--------------------------+-------+------------+
Using a LINQ expression and given a date range for example 2019-10-01 to 2019-10-03, I want to find the first employeeId of each type that has a record on each of the dates between the range meaning one record for 2019-10-01, another for 2019-10-02 and another for 2019-10-03, so the result should be
alberto | typeA
pedro | TypeB
So far I have this:
_context.Attendance
.Where(s => s.Date>= sm.InitialDate && s.Fecha <= sm.FinalDate)
I have tried a few things but I could not make it work.
You have made a good start, after filtering out the elements outside the date range, you should group by the type, then get the first one in each group:
var list = _context.Attendance
.Where(s => s.Date>= sm.InitialDate && s.Fecha <= sm.FinalDate)
.GroupBy(x => x.Type)
.Select(x => x.First())
.Select(x => new { x.EmployeeId, x.Type })
.ToList();

Linq Return List of Objects after max effective From Date

Hiiya,
So trying to work out a query that returns a list of objects based on its max effective from date before a selected datetime.
Principle Example
+----+--------------+------------+----------------+
| id | Employee_Num | Money_Owed | Effective_From |
+----+--------------+------------+----------------+
| 1 | 1 | 10.11 | 20/10/2017 |
+----+--------------+------------+----------------+
| 2 | 1 | 15.11 | 24/10/2017 |
+----+--------------+------------+----------------+
| 3 | 1 | 20.11 | 30/10/2017 |
+----+--------------+------------+----------------+
| 4 | 2 | 6.89 | 20/10/2017 |
+----+--------------+------------+----------------+
| 5 | 2 | 9.89 | 25/10/2017 |
+----+--------------+------------+----------------+
| 6 | 2 | 12.89 | 29/10/2017 |
+----+--------------+------------+----------------+
so say I want to return each employees record as of 21/10/17 I would expect the below to be returned as a list of objects (Entities)
+----+--------------+------------+----------------+
| id | Employee_Num | Money_Owed | Effective_From |
+----+--------------+------------+----------------+
| 1 | 1 | 10.11 | 20/10/2017 |
+----+--------------+------------+----------------+
| 4 | 2 | 6.89 | 20/10/2017 |
+----+--------------+------------+----------------+
Then as of 24/10/2017
+----+--------------+------------+----------------+
| id | Employee_Num | Money_Owed | Effective_From |
+----+--------------+------------+----------------+
| 2 | 1 | 15.11 | 24/10/2017 |
+----+--------------+------------+----------------+
| 4 | 2 | 6.89 | 20/10/2017 |
+----+--------------+------------+----------------+
Im guessing the Query should be something along these lines but cant work out what it should be.
var qry = from t in db.Entity.Where(x => x.Effective_From <= as_of_date)
.OrderBy(x => x.Employee_Num)
select new Entity { *need rest of entity fields* ,effective_from = Max(e => e.Effective_From) };
Any help to finish off or point me in a different direction would be appreciated...
I believe what you'd be looking to do would involve a GroupBy expression to group by employee number, ordered by Employee number and then effective from descending, then take the first available combination.
var qry = db.Entity.Where(x => x.Effective_From <= as_of_date)
.OrderBy(x => x.Employee_Num)
.ThenByDescending(x => X.Effective_From)
.GroupBy(x => x.Employee_Num)
.Select(g => g.FirstOrDefault())
.ToList();
This is if you want the actual entities. I'd avoid doing something like "select new" for an entity as while this will contain the data of the relevant entities, they aren't the same reference as far as the context is concerned. .Select() would be used to retrieve an anonymous type suited for some logic or to populate a view model for a front end, or a DTO for an API result.

Notify in .NET application if SQL data has changed

I have got two tables. Table A contains the main data in every change state, Table B has the detail data.
Table A
| ID | Name |
| 1 | House |
| 2 | Tree |
| 3 | Car |
Table B
| ID | FK | DateTime | Color | Type |
| 1 | 1 | 2017-26-01T13:00:00 | Red | Bungalow |
| 2 | 2 | 2017-26-01T13:05:00 | Brown | Oak |
| 3 | 1 | 2017-26-01T13:10:00 | Green | Bungalow |
| 4 | 3 | 2017-26-01T13:15:00 | Yellow | Smart |
| 5 | 1 | 2017-26-01T13:20:00 | White | Bungalow |
| 6 | 3 | 2017-26-01T13:25:00 | Black | Smart |
Result to watch
| ID | Name | DateTime | Color | Type |
| 1 | House | 2017-26-01T13:20:00 | White | Bungalow |
| 2 | Tree | 2017-26-01T13:05:00 | Brown | Oak |
| 3 | Car | 2017-26-01T13:25:00 | Black | Smart |
The current state of an entity in Table A is described by the record with the youngest timestamp in Table B.
Now, I want to be nofitied, if an entity gets a new state (new record in Table B) or a new entity is created (new records in Table A and B), i.e. it could look like.
New result to watch
| ID | Name | DateTime | Color | Type |
| 1 | House | 2017-26-01T13:20:00 | White | Bungalow |
| 2 | Tree | 2017-26-01T13:05:00 | Brown | Oak |
| 3 | Car | 2017-26-01T19:25:00 | Silver | Smart |
| 4 | Dog | 2017-26-01T20:25:00 | White / Black | Poodle |
With SqlDependency it is not possible to be notified for a statement which contains GROUP BY with MAX aggregate, window functions or TOP clause. So I have no idea how I can get the last detail data for an entity.
Is there any possibility to create a statement for this requirement or are there any other ways to be notified after changes for this result?
You can create and use SQL Triggers usin CLR
Here - SQL Trigger CLR

merge single table column with different types

Table Columns
or_cv_no
here is where 'cv_no' and 'or_no' stored
type
different types are 'CV' and 'OR'
amount
here is where 'cv_amt' and 'or_amt' stored
date
data that is being fetched has same date
my query is this
SELECT IIF(type = 'CV', or_cv_no) AS cv_no, IIF(type = 'CV', amount) AS cv_amt, IIF(type = 'OR', or_cv_no) AS or_no, IIF(type = 'OR', amount) AS or_amt FROM transacAmt
and the output is
how can i output it to look like this sample:
| cv_no | cv_amt | or_no | or_amt |
|---------------------------------|
| 1234 | 1,500 | 4321 | 1,200 |
|-------+--------+-------+--------|
| 7777 | 1,700 | 2222 | 1,760 |
|-------+--------+-------+--------|
| 1111 | 1,900 | 3333 | 1,530 |
|-------+--------+-------+--------|
| | | 5355 | 1,420 |
|-------+--------+-------+--------|
| | | 1355 | 4,566 |
EDIT: The output must be like this: marked 'x' must be removed.. or be filled by data

Categories