Orderby month and year using linq - linq

I'm fetching distinct months from database but the month values are in the form of month and year. ie, Jan-15,Feb-15. How do I get it in Ascending order of both month and year?
Right now I'm getting result as: Apr-15 Feb-15 Jan-15 Mar-15. But I want the result like this: Jan-15 Feb-15 Mar-15 Apr-15.
var months = ((from mnths in context.Table
orderby mnths.Month
select mnths.Month).Distinct()).ToList();
return months;
Thanks.

You can use DateTime.TryParseExact like this:
var months = ((from mnths in context.Table
orderby mnths.Month
select mnths.Month).Distinct()).ToList().OrderBy(m =>
{
DateTime month;
return DateTime.TryParseExact(m, new[] {"MMM-yy"}, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out month)
? month
: DateTime.MinValue;
}).ToList();
You need to call ToList before OrderBy so the original query is executed and you get an IEnumerable<string> instead of an IQueryable.

Just use .NET Sort Method.
First Get All dates from DB
var dates = ((from dts in context.Table
select dts).Distinct().ToList();
return dates;
And then Do
dates.Sort();
dates.Reverse();
And you'll get the result as yo want. (And Store Datetime in Db with type datetime not nvarchar or other).

Related

LINQ select row with max value after group by

I have following sql statement:
Select
tsl.Transaction_Id,
tsl.State_Id,
MAX(tsl."Timestamp")
from TransactionStatesLog tsl
group by tsl.Transaction_Id
How this statement can be translated to LINQ? I just want to select the whole row, where Timestamp is maximum of the group.
With this code i am able just to select TransactionId and max Timestamp from the group.
var states = (from logs in _context.TransactionStatesLog
group logs by new { logs.TransactionId } into g
select new
{
TransactionId = g.Key,
Timestamp = g.Max(x => x.Timestamp)
}).ToList();
I am working with ef core 3.1
Assuming you forgot to add tsl.State_Id to your SQL as grouping key as follows(otherwise that SQL does not work either):
Select
tsl.Transaction_Id,
tsl.State_Id,
MAX(tsl."Timestamp")
from TransactionStatesLog tsl
group by tsl.Transaction_Id, tsl.State_Id
If I understood you correctly you need to add StateId to grouping statement as well so that you will be able to select StateId and TransactionId.
So this should work:
var states = (from logs in _context.TransactionStatesLog
group logs by new { logs.TransactionId, logs.StateId } into g
select new
{
TransactionId = g.Key.TransactionId,
StateId = g.Key.StateId,
Timestamp = g.Max(x => x.Timestamp)
}).ToList();
See: Group by with multiple columns using lambda

Linq2DB adding unnecessary statements to query

I am trying to generate a query that gets the number of entries with dates that occur within each given month. The SQL form of the query I wish to generate goes like this:
SELECT
DatePart(Year, [t1].[StartTime]) as Year,
DatePart(Month, [t1].[StartTime]) as Month,
Count(*) as 'Visits',
Sum([t1].[PageCount]) as 'Total Pageviews'
FROM
[MyDatabase] [t1]
GROUP BY
DatePart(Year, [t1].[StartTime]),
DatePart(Month, [t1].[StartTime])
I tried the following Linq2DB code:
var query = from table in dataContext.MyDataContext(tablePath)
group table by new { table.StartTime.Year, table.StartTime.Month} into grp
select new { Month = grp.Key.Month, Year = grp.Key.Year,
TotalVisitors = grp.Count(),
TotalPageviews = grp.Sum(table2 => table2.PageCount) };
but the SQL query being generated by this is
-- SqlServer.2008 --
SELECT
[t1].[StartTime],
Count(*) as [c1],
Sum([t1].[PageCount]) as [c2]
FROM
[MyDatabase] [t1]
GROUP BY
DatePart(Year, [t1].[StartTime]),
DatePart(Month, [t1].[StartTime]),
[t1].[StartTime]
Why is [t1].[StartTime] rather than the month or year? And why is it grouping by that extra [t1].[StartTime] at the end? How do I generate the SQL query I have above using Linq2DB?
Please use the following workaround with Sql.AsSql function. We are trying to fix this longstanding issue.
var query = from table in dataContext.MyDataContext(tablePath)
group table by new { Sql.AsSql(table.StartTime.Year), Sql.AsSql(table.StartTime.Month)} into grp
select new { Month = Sql.AsSql(grp.Key.Month), Year = Sql.AsSql(grp.Key.Year),
TotalVisitors = grp.Count(),
TotalPageviews = grp.Sum(table2 => table2.PageCount) };

Ruby format DateTimeParameter in where query

I want to do a query like this:
bookings = Booking.where(user_id: #current_user.id, start_at: date.to_datetime)
The problem in this case is, that I just get results in bookings which match a timestamp 00:00:00 which is quite logical.
Is there a possibility to format the start_at parameter in the query to date, so that I just compare two dates and not datetimes?
Try convert your datetime field to date via SQL:
bookings = Booking.where(user_id: #current_user.id)
.where("DATE(start_at) = ?", date)
DATE() extracts the date part of a datetime expression.
Note: it does not works in PotsgreSQL
Or:
bookings = Booking.where(user_id: #current_user.id,
created_at: date.beginning_of_day..date.end_of_day)
How about this?
bookings = Booking.where(user_id: #current_user.id, start_at: start_date..end_date)
or
bookings = Booking.where(user_id: #current_user.id)
.where('start_at > ? AND start_at < ?', start_date, end_date)
where start_date and end_date are the two dates you wish to check between.

orderby nested linq

var query = from m in db.Members.Include("Companies.Projects.Experiences.ExperienceTags")
where m.MemberId == id
select m;
I would like to also from this query to orderby the project.enddate. How would I do that. Also enddate can be null which then I would like it to be today date when it orderby. And, a company might not always have a project either which then it should be orderby today date too.
here is a image of the ef data diagram a link
Since there is a many relationship you need to do a SelectMany like so:
var query = from m in db.Members.Include("Companies.Projects.Experiences.ExperienceTags")
where m.MemberId == id
orderby m.Companies.SelectMany(c => c.Projects).OrderByDescending(p => p.EndDate).FirstOrDefault() == null ?
DateTime.Today :
m.Companies.SelectMany(c => c.Projects).OrderByDescending(p => p.EndDate).FirstOrDefault()
select m;

Linq (MIN && MAX)

What is equal of below sql in LINQ
select MIN(finishTimestamp) AS FromDate, MAX(finishTimeStamp) AS ToDate From Transactions
??
from t in Transactions
select new {
FromDate = ?,
ToDate = ?
}
Thanks
To use multiple aggregates in Linq to SQL, on a table, without grouping, the only way I've found to avoid doing multiple queries, is to make a "fake group":
var q = from tr in dataContext.Transactions
group tr by 1 into g // Notice here, grouping by a constant value
select new
{
FromDate = g.Min(t => t.InvoiceDate),
ToDate = g.Max(t => t.InvoiceDate)
};
Kinda hacky, but the generated SQL is clean, and by doing so, you make only one query to the database.
You can just do
var transactionDates = from t in Transactions
select t.FinishTimeStamp;
var dates = new {
FromDate = transactionDates.Min(),
ToDate = transactionDates.Max()
};
You can also use the aggregate functions if you want (Example in VB)
Dim max = Aggregate tMax In Transactions Select tMax Into Max()

Resources