Linq on EF7 doesnt work with Joins and Dates? - asp.net

I am having some troubles running a query from a Controller on my ASP.NET MVC6 EF7 web app...
The Model and DbContext are in this previous ask: EF7 Incorrect configuration of the DBContext?
The problem appears when I try to run the following Linq query which contains a couple of joins and tries to get some entries from a Database for a particular date...
public IActionResult GetEntries(int year, int month, int day)
{
//_context.Database.SetCommandTimeout(180);
string dateTest = new DateTime(year, month, day).ToString("yyyy-MM-dd");
var results = (from c in _context.Comments
join r in _context.Reviews on c.ReviewId equals r.ReviewId
join f in _context.Films on c.ReviewId equals f.ReviewId
where c.Author.Equals("AuthorTest")
&& (c.Created.CompareTo(new DateTime(year, month, day, 0, 0, 0)) >= 0) && (c.Created.CompareTo(new DateTime(year, month, day, 23, 59, 59)) < 0)
&& !r.Status.Contains("Enabled")
select new
{
ReviewId = c.ReviewId,
ReviewStatus = r.Status,
Author = c.Author
});
var results2 = results.ToList();
return View(results2);
}
The Exception that I get is...
An exception of type 'System.Data.SqlClient.SqlException' occurred in
EntityFramework.Core.dll but was not handled in user code
Additional information: Timeout expired. The timeout period elapsed
prior to completion of the operation or the server is not responding.
The funny thing is.... if I run the EXACT same query without the following line, then it works perfectly
&& (c.Created.CompareTo(new DateTime(year, month, day, 0, 0, 0)) >= 0) && (c.Created.CompareTo(new DateTime(year, month, day, 23, 59, 59)) < 0)
So... the timeout exception thing doesn't make too much sense to me because once I remove the AND condition, it returns thousand of entries.
Also, if I plug that same query on a ASP.NET MVC5 EF6, the query works like a charm with the AND condition...
What am I missing here?
Finally, another thing that I tried was to create a single Linq query with no join and with the date condition and it works also perfectly...
public IActionResult GetEntries(int year, int month, int day)
{
//_context.Database.SetCommandTimeout(180);
string dateTest = new DateTime(year, month, day).ToString("yyyy-MM-dd");
var results = (from c in _context.Comments
where c.Author.Equals("AuthorTest")
&& (c.Created.CompareTo(new DateTime(year, month, day, 0, 0, 0)) >= 0) && (c.Created.CompareTo(new DateTime(year, month, day, 23, 59, 59)) < 0)
select new
{
ReviewId = c.ReviewId,
Author = c.Author
});
var results2 = results.ToList();
return View(results2);
}
Any pointers?
Thanks!

I think this is because your Linq to Entities provider doesn't know how to translate the CompareTo method to SQL. Try creating the dates you want to compare outside of your query and later try to compare them in your query as I show below:
var d1=new DateTime(year, month, day, 0, 0, 0);
var d2=new DateTime(year, month, day, 23, 59, 59);
var results = (from c in _context.Comments
join r in _context.Reviews on c.ReviewId equals r.ReviewId
join f in _context.Films on c.ReviewId equals f.ReviewId
where c.Author.Equals("AuthorTest")
&& c.Created >= d1 && c.Created<d2)
&& !r.Status.Contains("Enabled")
select new
{
ReviewId = c.ReviewId,
ReviewStatus = r.Status,
Author = c.Author
});

Related

Get Last Month Date In Flutter / Dart

in flutter we can get current month using this
var now = new DateTime.now();
var formatter = new DateFormat('MM');
String month = formatter.format(now);
But how to get the last month date? Especially if current date is January (01). we can't get the right month when we use operand minus (-) , like month - 1.
You can just use
var prevMonth = new DateTime(date.year, date.month - 1, date.day);
with
var date = new DateTime(2018, 1, 13);
you get
2017-12-13
It's usually a good idea to convert to UTC and then back to local date/time before doing date calculations to avoid issues with daylight saving and time zones.
We can calculate both first day of the month and the last day of the month:
DateTime firstDayCurrentMonth = DateTime.utc(DateTime.now().year, DateTime.now().month, 1);
DateTime lastDayCurrentMonth = DateTime.utc(DateTime.now().year, DateTime.now().month + 1).subtract(Duration(days: 1));
DateTime.utc takes in integer values as parameters: int year, int month, int day and so on.
Try this package, Jiffy, it used momentjs syntax. See below
Jiffy().subtract(months: 1);
Where Jiffy() returns date now. You can also do the following, the same result
var now = DateTime.now();
Jiffy(now).subtract(months: 1);
We can use the subtract method to get past month date.
DateTime pastMonth = DateTime.now().subtract(Duration(days: 30));
Dates are pretty hard to calculate. There is an open proposal to add support for adding years and months here https://github.com/dart-lang/sdk/issues/27245.
There is a semantic problem with adding months and years in that "a
month" and "a year" isn't a specific amount of time. Years vary by one
day, months by up to three days. Adding "one month" to the 30th of
January is ambiguous. We can do it, we just have to pick some
arbitrary day between the 27th of February and the 2nd of March.
That's why we haven't added month and year to Duration - they do not
describe durations.
You can use the below code to add months in a arbitrary fashion (I presume its not completely accurate. Taken from the issue)
const _daysInMonth = const [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
bool isLeapYear(int value) =>
value % 400 == 0 || (value % 4 == 0 && value % 100 != 0);
int daysInMonth(int year, int month) {
var result = _daysInMonth[month];
if (month == 2 && isLeapYear(year)) result++;
return result;
}
DateTime addMonths(DateTime dt, int value) {
var r = value % 12;
var q = (value - r) ~/ 12;
var newYear = dt.year + q;
var newMonth = dt.month + r;
if (newMonth > 12) {
newYear++;
newMonth -= 12;
}
var newDay = min(dt.day, daysInMonth(newYear, newMonth));
if (dt.isUtc) {
return new DateTime.utc(
newYear,
newMonth,
newDay,
dt.hour,
dt.minute,
dt.second,
dt.millisecond,
dt.microsecond);
} else {
return new DateTime(
newYear,
newMonth,
newDay,
dt.hour,
dt.minute,
dt.second,
dt.millisecond,
dt.microsecond);
}
}
To get a set starting point at the start of a month, you can use DateTime along with the Jiffy package.
DateTime firstOfPreviousMonth
= DateTime.parse(
Jiffy().startOf(Units.MONTH)
.subtract(months: 1)
.format('yyyy-MM-dd'). //--> Jan 1 '2021-01-01 00:00:00.000'
);
var fifthOfMonth
= firstOfPreviousMonth.add(Duration(days: 4)); //--> Jan 5 '2021-01-05 00:00:00.000'
or
DateTime endOfPreviousMonth
= DateTime.parse(
Jiffy().endOf(Units.MONTH)
.subtract(months: 2)
.format('yyyy-MM-dd'). //--> Dec 30 '2020-12-31 00:00:00.000'
// endOf always goes to 30th
);
var previousMonth
= endOfPreviousMonth.add(Duration(days: 2)); //--> Jan 1 '2021-01-01 00:00:00.000'
DateFormat('MMMM yyyy')
.format(DateTime(DateTime.now().year, DateTime.now().month - 2)),
List<DateTime> newList = [];
DateFormat format = DateFormat("yyyy-MM-dd");
for (var i = 0; i < recents.length; i++) {
newList.add(format.parse(recents[i]['date'].toString()));
}
newList.sort(((a, b) => a.compareTo(b)));
var total = 0;
for (var i = 0; i < newList.length; i++) {
if (DateTime.now().difference(newList[i]).inDays < 30) {
print(newList[i]);
total++;
}
}
print(total);
You can use this to fetch the last 30 days.
In addition to Günter Zöchbauer Answer
var now = new DateTime.now();
String g = ('${now.year}/ ${now.month}/ ${now.day}');
print(g);

Linq to Entity, selecting group with or without value

Hi Need some help with LINQ query.
I have entity called Shift. This entity has several value field but the ones I am intressted in are ShiftID (int), ShiftDate (DateTime) and GrossMount (decimal(10,2). And this needs to be grouped by month (binding this to a graph in ASP.NET).
I need data for the last 12 months grouped by month.
I have come a bit on the way with this post: Linq to Entity, selecting group without value but not quite all the way.
This is my code for now:
public IQueryable<Shift> GetPastMonths(int months, string accountNumber)
{
_context = new EtaxiEnteties();
var _date = DateTime.Today;
var _firstOfMonth = new DateTime(_date.Year, _date.Month, 31);
var _twelveMonthAgoFirstOfMonth = _firstOfMonth.AddMonths(-12);
// Generate a collection of the months and years for the last 12 months
var _monthYears = Enumerable.Range(-12, 12).Select(monthOffset => { var monthDate = _firstOfMonth.AddMonths(monthOffset); return new { y = monthDate.Year, m = monthDate.Month }; });
var _data = (from _monthYear in _monthYears
join _i in
(from _i in _context.Shifts.Where(acc => acc.Account.AccountNumber == accountNumber)
where _i.ShiftDate >= _twelveMonthAgoFirstOfMonth && _i.ShiftDate < _firstOfMonth
group _i by new { y = _i.ShiftDate.Year, m = _i.ShiftDate.Month } into g
select new { ShiftID = g.Key, GrossAmount = g.Count() }) on _monthYear equals _i.ShiftID into j
from _k in j.DefaultIfEmpty()
select new Shift() { ShiftDate = new DateTime(_monthYear.y, _monthYear.m, 1), GrossAmount = _k != null ? _k.GrossAmount : 0 });
return _data as IQueryable<Shift>;
}
Now I have in return a collection of Shift objects, grouped by month but still missing the GrossAmount. Althoug i would need this from today date (only getting from 1 of current month).
Believe this is my main problem: GrossAmount = g.Count(), but I am not sure
Any LINQ specialist out there that could give me a push?
Use GrossAmount = g.Sum(x => x.GrossAmount) to calculate total GrossAmount value of grouped Shift entities. I believe you have typo in GrossAmount (GrossMount) property name.

how to get records from database based on date range in asp.net linq

I have develop a small web application in that i'm using entity frame work .i want get the records based on the date range and bind that data in gridview how can i write a query using linq..please help me..Here i have post my code what i have try to get records please .....
var query = from p in entity.Payments
join D in entity.Debit_Method on p.Debit_Method_ID equals D.Debit_Method_ID
join pt in entity.Payment_Type on p.Payment_Type_ID equals pt.Payment_Type_ID
where p.Client_Pmt_Date >='1998-12-01' && p.Client_Pmt_Date<='1999-08-01' && p.Loan_ID=loanid
select new
{
p.Pmt_ID,
p.Loan_ID,
p.Client_Pmt_Date,
p.MtgSvr_Pmt_Start_Date2,
D.Debit_Method_Desc,
p.Total_Debit_Amt,
p.CreditAmt,
p.LenderAmt,
pt.Payment_Type_Desc,
p.Return_Code,
p.Returned_Date
//p.Pmt_ID,
// D.Debit_Method_Desc,
// pt.Payment_Type_Desc,
// p.Client_Pmt_Date,
// p.MtgSvr_Pmt_Start_Date2,
// p.Amt,
// p.CreditAmt,
// p.Loan_ID,
// p.Pmt_Comments
// p.Loan_ID,
};
grdPayments.DataSource = query.ToList();
grdPayments.DataBind();
}
You will need to compare the Date to a DateTime object rather than a string. Here is a LINQ example with POCO (Plain Old CLR Objects):
var dates = new List<DateTime> { new DateTime(2011, 1, 1), new DateTime(2010, 1, 1), new DateTime(2009, 1, 1) };
var result1 = from x in dates where x < new DateTime(2011, 1, 1) && x > new DateTime(2009,1,1) select x;
var result2 = dates.Where(x => x < new DateTime(2011, 1, 1) && x > new DateTime(2009,1,1));

how to calculate the working days in between two different dates in asp.net

i have two textbox using calaendarExtender and one label.
My needed is if i select two different dates in calendar extender the number of working days(excluding Sunday) to be automatically display in the label.
can any one help me.....
im new in ASP.net......
What about this:
DateTime start = new DateTime(2010, 12, 1);
DateTime end = new DateTime(2010, 12, 31);
int workdays = 0;
DateTime aux = start;
while(aux <= end)
{
aux = aux.AddDays(1);
if (aux.DayOfWeek != DayOfWeek.Sunday)
workdays++;
}
yourLabel.Text = workdays.ToString();

Entity Framework and Linq - Comparing DateTime

I have this code
public List<CalendarData> GetCalendarData(DateTime day)
{
List<CalendarData> list = new List<CalendarData>();
using (dataContext = new VTCEntities())
{
DateTime test = new DateTime(2010, 10, 20, 17, 45, 0);
var data = from z in dataContext.ReservationsSet
where z.start_time.Value == test
select z;
foreach (var r in data)
What I'd like to do is have this
var data = from z in dataContext.ReservationsSet
where z.start_time.Value == day
select z;
the problem I have is that z.start_time has the time part also. The DateTime day doesn't have the time part recorded. Is there a way to compare the the date part of without getting this error
The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
when I do this
var data = from z in dataContext.ReservationsSet
where z.start_time.Value.Date == test
select z;
One option is to compute two values, like this:
DateTime day = ...;
DateTime nextDay = day.AddDays(1);
var data = from z in dataContext.ReservationsSet
where z.start_time.Value >= day &&
z.start_time.Value < nextDay
select z;
You can't use .Date in Entity Framework. The easiest way I know to handle this is to make a minimum + maximum day:
DateTime test = new DateTime(2010, 10, 20, 17, 45, 0);
DateTime startDay = test.Date;
DateTime endDay = startDay.AddDays(1);
var data = from z in dataContext.ReservationsSet
where z.start_time.Value >= startDay && z.start_time.Value < endDay
select z;

Resources