multiple linq orderby not working - c#

I have multiple OrderBy but only the first order column is working
public static List<vwData> GetAllData(string startDate, string endDate)
{
DateTime dtStart = Convert.ToDateTime(startDate).Date;
DateTime dtEndDate = Convert.ToDateTime(endDate).Date;
var entities = new DataEntities();
var query = from c in entities.vwData
let eventDate = EntityFunctions.TruncateTime(c.EventCreateDate)
orderby c.EventCreateDate ascending, c.StartDateTime ascending
where eventDate >= dtStart && eventDate <= dtEndDate
select c;
return query.ToList();
}

Consider using ThenBy:
public static List<vwData> GetAllData(string startDate, string endDate)
{
DateTime dtStart = Convert.ToDateTime(startDate).Date;
DateTime dtEndDate = Convert.ToDateTime(endDate).Date;
var entities = new DataEntities();
var query = from c in entities.vwData
let eventDate = EntityFunctions.TruncateTime(c.EventCreateDate)
orderby c.EventCreateDate ascending
thenby c.StartDateTime ascending
where eventDate >= dtStart && eventDate <= dtEndDate
select c;
return query.ToList();
}

Orderby should be after condition check and default ordering is ascending
var query = from c in entities.vwData
let eventDate = EntityFunctions.TruncateTime(c.EventCreateDate)
where eventDate >= dtStart && eventDate <= dtEndDate
orderby c.EventCreateDate, c.StartDateTime
select c;
return query.ToList();
OR
Using Linq, we can do as follows
var query = entities.vwData.Where(i =>
{
var eventDate = EntityFunctions.TruncateTime(i.EventCreateDate);
if (eventDate >= dtStart && eventDate <= dtEndDate)
return true;
return false;
})
.OrderBy(j => j.EventCreateDate)
.ThenBy(k => k.StartDateTime)
.Select(m => m);
return query.ToList();

Try following query. It will help you:
var query = entities.vwData.Where(i => EntityFunctions.TruncateTime(i.OrderDate) >= dtStart && EntityFunctions.TruncateTime(i.OrderDate) <= dtEndDate )
.OrderBy(j => j.EventCreateDate)
.ThenBy(k => k.StartDateTime)
.Select(m => m);
return query.ToList();

Related

LINQ DateTime Query that ignores milliseconds

x.CreateDate DateTime is stored in our database down to milliseconds. My dateTimePicker values startdate and enddate only allows for querying down to seconds.
How can change my query to ignore the milliseconds of x.CreateDate? I thought the code I wrote below would work but it is not.
if (stardDateIsValid && endDateIsValid && startdate == enddate)
query = _context.Logs
.Where(x => x.ApplicationID == applicationId &&
x.CreateDate.AddMilliseconds(-x.CreateDate.Millisecond) == startdate)
.OrderByDescending(x => x.ID)
.Take(count);
var query = from l in _context.Logs
where l.ApplicationID == applicationId
&& SqlMethods.DateDiffSecond(l.CreateDate,startdate) == 0
orderby l.ID descending
select l).Take(count);
This avoids converting every date in you table into a string and the subsequent string comparison, by comparing the two dates as dates.
Getting CreateDate and startdate in the same format will help you compare apples to apples. This should accomplish that.
if (stardDateIsValid && endDateIsValid && startdate == enddate)
query = _context.Logs
.Where(x => x.ApplicationID == applicationId &&
x.CreateDate.ToString(#"MM/DD/YYYY h:mm:ss") == startdate.ToString(#"MM/DD/YYYY h:mm:ss")
.OrderByDescending(x => x.ID)
.Take(count);
I have no idea why I could not get any results from the queries posted above as I tried several variations of their themes. However I did get it working correctly by adding milliseconds to the startdate and enddate variables and it s working.
if (stardDateIsValid && endDateIsValid)
startdate = startdate.AddMilliseconds(000);
enddate = enddate.AddMilliseconds(999);
query = _context.Logs.Where(x => x.ApplicationID == applicationId && x.CreateDate >= startdate && x.CreateDate <= enddate).OrderByDescending(x => x.ID).Take(count);
You can create extension method.
public const long TicksPerMillisecond = 10000;
public const long TicksPerSecond = TicksPerMillisecond * 1000;
public static bool IsEqualIgnoreMilliseconds(this DateTime date, DateTime compareDate)
{
long tickDiff = date.Ticks - compareDate.Ticks;
return tickDiff > 0 ? tickDiff < TicksPerSecond : tickDiff < -TicksPerSecond;
}
Then you can use this:
if (stardDateIsValid && endDateIsValid && startdate == enddate)
query = _context.Logs
.Where(x => x.ApplicationID == applicationId &&
x.CreateDate.IsEqualIgnoreMilliseconds(startdate)
.OrderByDescending(x => x.ID)
.Take(count);

Linq to Sql get today date only data from db

i am unable to get the data from db with date only comparison. In Db InDateTime datatype is DateTime
using (HatronEntities context = new HatronEntities())
{
DateTime date = DateTime.Now.Date;
var AttendData = (from c in context.tbl_CoachMobAttendDetails
where c.CoachId == model.Id && c.InDateTime.Value.Date ==date
select c).FirstOrDefault();
}
using (HatronEntities context = new HatronEntities())
{
DateTime date = DateTime.Today;
DateTime until = date.AddDays(1);
var AttendData = (from c in context.tbl_CoachMobAttendDetails
where c.CoachId == model.Id &&
c.InDateTime.Value >= date &&
c.InDateTime.Value < until
select c).FirstOrDefault();
}
You didn't say initially that it was Linq To Entity Framework - but you say Linq To SQL! Then:
using (HatronEntities context = new HatronEntities())
{
DateTime date = DateTime.Today;
var AttendData = (from c in context.tbl_CoachMobAttendDetails
where c.CoachId == model.Id &&
DbFunctions.TruncateTime( c.InDateTime ) == date
select c).FirstOrDefault();
}
You can try like this:
c.InDateTime.Year == date.Year && c.InDateTime.Month == date.Month
&& c.InDateTime.Day == date.Day
or like
DbFunctions.TruncateTime(c.InDateTime.Value.Date) == date.Date
You can use DbFunctions.TruncateTime method:
DbFunctions.TruncateTime(c.InDateTime.Value.Date) == date.Date
Try Like this
c.InDateTime.Value.Date.Year == date.Year &&
c.InDateTime.Value.Date.Month == date.Month &&
c.InDateTime.Value.Date.Day == date.Day

LInq to Entity select new COUNT where

I've created the most complex linq query ever, but still do not have exactly what I need. From this query, I need to know how many related students in the EventStudents table that have a DateDeleted == null. So, the StudentCount = ev.EventStudents - where DateDeleted == null .Count().
Can anyone help with this please?
var inf = (from ev in db.Events
where (ev.StartDate >= beginDate && ev.StartDate <= endDate)
&& ev.DeletedDate == null
orderby ev.StartDate descending
select new
{
EventID = ev.EventID,
EventTitle = ev.Title,
EventDate = ev.StartDate,
StudentCount = ev.EventStudents.Count(),
CreatedUsername = ev.CreatedUsername
}).AsEnumerable().Select(x => new
{
EventID = x.EventID,
EventTitle = x.EventTitle,
EventDate = x.EventDate,
StudentCount = x.StudentCount,
CreatedUsername = x.CreatedUsername,
CreatedFullname = sortedUserDictionary.Where(u => u.Value == x.CreatedUsername)
.Select(f => f.Key)
.FirstOrDefault() ?? x.CreatedUsername
});
Change ev.EventStudents.Count() to ev.EventStudents.Count(es => es.DateDeleted == null).

LINQ return expression if expression does not match

I'm not sure the title explains the problem well, so here is the code. I want to return an anonymous object to bind my grid to. In that grid, I want to change usernames to fullnames, but only if I HAVE the fullname to match the username. In the query below, I get CreatedFullname IF CreatedUsername exists in userModels. If it does not exists then I don't get the record at all. What I wnat is to get the record, show UserFullname if it is available in userModels, if it is not I want to return x.CreatedUsername.
var inf = (from ev in db.Events
where (ev.StartDate >= beginDate && ev.StartDate <= endDate)
orderby ev.StartDate descending
select new
{
EventID = ev.EventID,
EventTitle = ev.Title,
EventDate = ev.StartDate,
StudentCount = ev.EventStudents.Count(),
CreatedUsername = ev.CreatedUsername
}).AsEnumerable().Select(x => new {EventID = x.EventID,
EventTitle = x.EventTitle,
EventDate = x.EventDate,
StudentCount = x.StudentCount,
CreatedUsername = x.CreatedUsername,
CreatedFullname =
userModels.Where(u => u.Username == x.CreatedUsername).FirstOrDefault().UserFullName
});
userModels is a custom object that has Username, UserFullname, Department, etc. It was collected from ActiveDirectory on pageload, based on beginDate and endDate.
You can do this:
CreatedFullname =
userModels.Where(u => u.Username == x.CreatedUsername)
.Select(x => x.UserFullName)
.FirstOrDefault() ?? x.CreatedUsername
Or this:
var inf =
(from x in
(from ev in db.Events
where (ev.StartDate >= beginDate && ev.StartDate <= endDate)
orderby ev.StartDate descending
select new
{
EventID = ev.EventID,
EventTitle = ev.Title,
EventDate = ev.StartDate,
StudentCount = ev.EventStudents.Count(),
CreatedUsername = ev.CreatedUsername
})
.AsEnumerable()
let model = userModels.FirstOrDefault(u => u.Username == x.CreatedUsername)
select new
{
EventID = x.EventID,
EventTitle = x.EventTitle,
EventDate = x.EventDate,
StudentCount = x.StudentCount,
CreatedUsername = x.CreatedUsername,
CreatedFullname = (model != null)
? x.modelUserFullName
: x.CreatedUsername
});

Get Sum of a field in Linq with Group by

I am having an SQL:
SELECT ApplicationNo,COUNT(ApplicationNo) AS CNT, SUM(Amount) as AMNT
FROM Payments where (TYPE=1 AND Position=1) and (Date>='2011-01-01')
and (Date<='2012-01-01')
GROUP BY ApplicationNo
Is there a way in which I can convert the same in Linq?
var q = (from payments in context.Payments
where payments.Date >= fromdate && payments.Date <= todate
group payments by new { payments.ApplicationId } into g
select new
{
applicationId=g.Key,
Amount=g.Sum(a=>a.Amount)
});
If I write the same in Linq and then Group by in the end, I am not getting the same result.
DateTime fromDate = new DateTime(2011, 1, 1);
DateTime toDate = new DateTime(2011, 1, 1);
var query = from p in db.Payments
where p.Type == 1 && p.Position == 1 &&
p.Date >= fromDate && p.Date <= toDate
group p by p.ApplicationNo into g
select new {
ApplicationNo = g.Key,
CNT = g.Count(),
AMNT = g.Sum(x => x.Amount)
};
Here db is your context class.

Categories