Converting a SQLServer to Linq Query - c#

I would like to know what is the correct way to convert this query to LINQ.
SELECT DISTINCT ( CONVERT(date,FechaCreacion)) FROM Tabla
where ID = 4
order by CONVERT(date,FechaCreacion) desc
OFFSET (0 * 20) ROWS
FETCH NEXT 20 ROWS ONLY;
With this query it brings me this data:
1. 2021-03-16
2. 2021-03-15
3. 2021-03-14
4. 2021-03-13
5. 2021-03-11
6. 2021-03-09
7. 2021-03-02
8. 2021-02-28
9. 2021-02-25
10. 2021-02-24
11. 2021-02-23
12. 2021-02-22
13. 2021-02-21
14. 2021-02-19
15. 2021-02-10
16. 2020-11-30
17. 2020-10-05
18. 2020-02-18
LINQ:
var query = (from sp in esquema.Tabla
where sp.ID== 4
orderby DbFunctions.TruncateTime(sp.FechaCreacion) descending
select new
{
fechacreacion = DbFunctions.TruncateTime(sp.FechaCreacion)
}
).Skip(0* 20).Take(20).ToList().Distinct();
With LINQ it brings me less data than the query made directly in SQL Server
1. 2021-03-16
2. 2021-03-15
3. 2021-03-14
4. 2021-03-13
5. 2021-03-11
6. 2021-03-09
7. 2021-03-02
8. 2021-02-28
9. 2021-02-25
10. 2021-02-24
11. 2021-02-23

You have applied Distinct to already paginated result. That's why result is different.
var query =
from sp in esquema.Tabla
where sp.ID == 4
orderby DbFunctions.TruncateTime(sp.FechaCreacion) descending
select new
{
fechacreacion = DbFunctions.TruncateTime(sp.FechaCreacion)
};
var query = query
.Distinct()
.Skip(0 * 20)
.Take(20)
.ToList();

Related

group by linq to entity query to get one record having latest timestamp by joining tables

There are two tables and using linq query to get records. From second table, there can be multiple rows corresponding to first table with date timestamp... based on below query, I am getting all records, but is there a way we can get the row from second table which has latest timestamp ?
Table Parent
ID Name
1 M
2 N
3 O
4 P
5 Q
Table Child
Id fkID DateTime
1 2 01/12/2021 09:12:20
2 2 01/12/2021 09:13:20
3 2 01/12/2021 09:14:20
4 2 01/12/2021 09:15:20
5 2 01/12/2021 **09:16:20**
Linq query:
from p in Parent
join c in Child on p.id equals c.fkId into cJoin
from cJoin in cJoin.DefaultIfEmpty()
select new TempResponse
{
Id = p.Id,
Name = p.Name,
Date = c.Date
}
I am getting 10 records using above query but just need 5 records i.e. from child table instead of all 5 records, we need a record that has latest time stamp
**expected output**
1 M
2 N 01/12/2021 09:16:20
this record is 5'th record from child table because this one has latest date time stamp
( latest record )
3 O
4 P
5 Q
Is there any way we can use group by and get the record that has latest time stamp from second table ?
Assuming you have defined navigation properties for the FK, I would use a query like;
dbContext.Child.Where(c => c.Date == c.Parent.Child.Max(c2 => c2.Date))
I believe you can use:
var ans = from p in Parent
join cmax in (
from c in Child
group c by c.fkId into cg
select cg.OrderByDescending(c => c.Date).FirstOrDefault())
on p.Id equals cmax.fkId into cJoin
from c in cJoin.DefaultIfEmpty()
select new TempResponse {
Id = p.Id,
Name = p.Name,
Date = c != null ? c.Date : null
};
Note that the order of results seems to vary on SQL Server unless you add another orderby clause before the select to force an order.

C# entity framework String Canonical Functions

How to use the Right function in entity framework query?
I have this sql query
SELECT RIGHT('0' + '4'), DATEDIFF(MINUTE, DateReceived, GETDATE()) % 60), 2)
FROM mytable //RESULTS = 04
The Right function will basically add 0 infront if the passed string's length is less than 2.
Now I want to do the same thing in entity framework query:
var query = (from b in sovDB.myTable
select new
{
myMinutes = Right("0"+ (SqlFunctions.DateDiff("MINUTE", b.DateReceived,
SqlFunctions.GetDate()) % 60),2)
}).ToList();
But it doesnt work, somehow the Right function is not supported.
Just had the same issue when converting an old stored procedure to entity. I used SqlFunctions.Replicate which did the trick and Entity Framework had no complaints!
var query = (from b in sovDB.myTable
select new
{
myMinutes = SqlFunctions.Replicate("0", 2 - (SqlFunctions.DateDiff("MINUTE", b.DateReceived, GetDate()) % 60).Length) + (SqlFunctions.DateDiff("MINUTE", b.DateReceived, GetDate()) % 60)
}).ToList();
Try to explicitly convert calculated minute to string:
var query = (from b in sovDB.myTable
select new
{
myMinutes = Right("0" + SqlFunctions.StringConvert((int)(SqlFunctions.DateDiff("MINUTE", b.DateReceived, SqlFunctions.GetDate()) % 60)), 2)
}).ToList();

How to concat with linq?

I have this tables at sql server:
id_service name
1 ejemplo 1
2 ejemplo 2
id_service id_quality
1 1
1 2
id_quality quality
1 simple
2 full
and Im trying to get this:
id_service qualities
1 Simple \n Full
I´m working with linq, is there any way to do it???
I have this so far, but it returns two rows instead of one as I need
var services = from service in dc.service
join s_quality in dc.service_quality
on service.id_service equals s_quality.id_service
join qualityObj in dc.quality
on s_quality.id_quality equals qualityObj.id_quality
select new {service.id_service, qualityObj.quality1};
GridView1.DataSource = services;
GridView1.DataBind();
The ending grid should look like this:
id_service name quality available
1 Company 1 1 - simple
2 - full
--------------------------------------------------------
2 Company 2 1 - simple
(this column should have grouped or concat results)
var servicios = from servicio in dc.servicio
join s_calidad in dc.servicio_calidad
on servicio.id_servicio equals s_calidad.id_servicio
join calidadObj in dc.calidad
on s_calidad.id_calidad equals calidadObj.id_calidad
group new {servicio.id_servicio, calidadObj.calidad1} by servicio.id_servicio into grouping
select new { groupning.Key, Concat = string.Join(",", grouping.Select(g => g.calidad1)) };
You can write your own concatenation logic for Concat property in the anonimous type

SQL Time Duration Between Records

I have the following table:
CamId RegNumber DateSeen
5 G1234B 18/02/2014 11:54
3 G1234B 18/02/2014 11:51
5 G11854 18/02/2014 11:50
3 G11854 18/02/2014 11:49
3 G24581 18/02/2014 11:48
I need to know the time taken from when a registration number is seen at CamId 3 to CamId 5, a reg number must exist in both CamId 3 and 5 for this to work.
The result i am looking for is a list of registration numbers together with a time difference in seconds (for the purpose of this demo in minutes):
RegNumber Duration
G1234B 3
G11854 1
I then want to add up all these durations and get the median or average value.
Hopefully someone can assist, a linq sql statement would be ideal.
You can use Enumerable.GroupBy, then select the latest record with CamId == 5, subtract it with the earliest record with CamId == 3 and use TimeSpan.TotalSeconds.
var query = db.Registration
.GroupBy(r => r.RegNumber)
.Select(grp => new
{
RegNumber = grp.Key,
Duration = (grp.Where(r => r.CamId == 5)
.OrderByDescending(r => DateSeen)
.Select(r => r.DateSeen)
.FirstOrDefault()
- grp.Where(r => r.CamId == 3)
.OrderBy(r => DateSeen)
.Select(r => r.DateSeen)
.FirstOrDefault()).TotalSeconds
});
Update: "Would you be able to provide the above in an SQL statement?"
WITH CTE AS
(
SELECT [CamId], [RegNumber], [DateSeen],
Duration = DATEDIFF(second,
(SELECT MIN(DateSeen)FROM dbo.Registration r2
WHERE r1.RegNumber=r2.RegNumber
AND r2.CamId = 3),
(SELECT MAX(DateSeen)FROM dbo.Registration r2
WHERE r1.RegNumber=r2.RegNumber
AND r2.CamId = 5)),
RN = ROW_NUMBER() OVER (PARTITION BY RegNumber ORDER BY DateSeen)
FROM dbo.Registration r1
)
SELECT [RegNumber], [Duration]
FROM CTE
WHERE [Duration] IS NOT NULL AND RN = 1
Demo

linq sql where closest to number

i have a table
Id Number
1 9
2 10
3 12
4 19
5 20
select Id where Number is closest to 18
it should return row 4 which is 19
how do i write this in linq and tsql? thanks
(from q in table
orderby Math.Abs(18 - q.Number)
select q).FirstOrDefault()
and
SELECT TOP 1
*
FROM
table
ORDER BY
ABS(10 - Number)
and for a datetime
var nearTo = new DateTime(1999, 12, 31);
(from q in table
orderby Math.Abs((nearTo - q.Date).TotalSeconds)
select q).FirstOrDefault()

Categories

Resources