how can i wirte linq to compair the year and month f - c#

I am trying to fetch record from my database year and month vise
I have write following linq
Connection cn = new Connection();
IMongoDatabase db = cn.ConnectionString();
var collection = db.GetCollection<HolidayListModel>("Holiday");
var filter = Builders<HolidayListModel>.Filter.Eq("business_id", businessid);
try
{
var obj = collection.Find(filter).ToListAsync();
if (obj != null && obj.Result != null)
{
if (month == "All")
{
holidaylist = obj.Result.Where(x => DateTime.Parse(x.date).Year == selectedyear).OrderBy(x => DateTime.Parse(x.date)).Select(x => new HolidayListModel()
{
_id = x._id,
business_id = x.business_id,
festival = x.festival,
date = x.date,
day = x.day
}).ToList();
}
else
{
holidaylist = (from x in obj.Result where (( x.date == month )) select x).ToList();
}
Here with lambda expression I got the data year vise using query expression I can't find a way to fetch data using year and month
Can someone guide me how can I write linq for this problem

This is usually done simply by using a start/end value; so foo.Year == selectedYear or foo.date == month becomes simply foo >= #start && foo < #end (the end is usually exclusive, so for a "year" check, that would be 1 Jan of the next year; for a "month" check it would be the 1st of the next month; this means that times in the last day are still always treated correctly).
If you are storing your dates in mongodb as strings that are ISO 8601 or similar, you could also do the same thing simply with string comparisons, without any "parse" logic.

Related

Linq searches for recent birthdays (within 15 days)

How to use Linq
A table
Field Birthday
Linq searches for recent birthdays (within 15 days)
from a in Employee where a.PositionStatus == true select new{ a.Name,a.Birthday}
Try below query
var fromdate = DateTime.Now;
var todate = DateTime.Now.AddDays(15);
var result =
(
from a in Employee
where a.PositionStuats==true && a.DateOfBirth.Value.Month >= fromdate.Month &&
a.DateOfBirth.Value.Month <= todate.Month &&
a.DateOfBirth.Value.Day >= fromdate.Day && a.DateOfBirth.Value.Day <= todate.Day
select new{ a.Name,a.Birthday}
).ToList();
Depending on your entity frame work version you can also replace a.DateOfBirth.Value.Month with a.DateOfBirth.Month.

How to pass 2 dates in .Where?

currently in the code I am outputting the employees table which have end dates of anything from before today's date and up to 90 days. I am trying to make it so only employees with maximum -30 days and + 90 of today's date.
(Fairly new so be easy)
(NOT SURE HOW TO CORRECTLY USE 2 DATES FOR .ADDDAYS )
Thanks
public ActionResult Index()
{
var employees = db.employees;
var today = DateTime.Today.AddDays(90);
var past = DateTime.Today.AddDays(-30);
var q = db.employees.Where(t => t.EndDate <= today );
return View(q.OrderByDescending(t => t.EndDate));
}
Why can't you use a AND (&&) condition like
var q = db.employees.Where(t => t.EndDate <= today && t.EndDate >= past);
It is simple by using conditional-AND && operator & combining both queries as single line:
var q = db.employees.Where(t => t.EndDate >= past && t.EndDate <= today)
.OrderByDescending(t => t.EndDate);
return View(q);
Try following code. You can add the OrderByDescending(t => t.EndDate) on the first line of code.
var q = db.employees.Where(t => t.EndDate >= past && t.EndDate<= today)OrderByDescending(t => t.EndDate);
return view(q);

C# EF: How to search between two dates in EF but want to exclude time from data

i do not know how to execlude time from data when doing comparison in EF.
using (var db = new DbContext())
{
var query = from n in db.BDatas
orderby n.AddDate,n.CountryCode
where n.CountryCode=="GB"
&& (n.AddDate >= stdate.Date && n.AddDate <= etdate)
select n;
}
i guess my above query will include date and time when comparision will occur. so tell me what to do?
You don't need to exclude time from SQL comparison. You can just exclude time from parameters which you are passing:
using (var db = new DbContext())
{
var startDate = stdate.Date;
var endDate = etDate.Date.AddDays(1);
var query = from n in db.BDatas
orderby n.AddDate,n.CountryCode
where n.CountryCode=="GB"
&& (n.AddDate >= startDate && n.AddDate < endDate)
select n;
}
Note that I used < endDate and added one more day to it. Thus you will have results from any time of previous day.
If Your Field AddDate is a DateTime Field you can do it as follows
using (var db = new DbContext())
{
var query = (from n in db.BDatas
orderby n.AddDate,n.CountryCode
where n.CountryCode=="GB"
select n).Where(n => n.AddDate.Date >= stdate.Date &&
n.AddDate.Date <= etdate).ToList();
}
Using Entity Framework Core
Had a Model "Fire", needed to pass date string to date from format "yyyy-MM-dd"
Injected my dbContext in my Service class
First cast date string to DateTime and used them to fetch records as shown below
var sDate = DateTime.ParseExact(startDate, "yyyy-MM-dd", CultureInfo.InvariantCulture);
var eDate = DateTime.ParseExact(endDate, "yyyy-MM-dd", CultureInfo.InvariantCulture);
var fireData = await _dbContext.Fire.Where(b => (b.CreatedAt >= sDate && b.CreatedAt < eDate) && b.UploadStatus == "False").ToListAsync();
return fireData;

Linq Entity Framework grouping and joins on names, year and month

I am developing an ASP.NET MVC Appliction with MYSQL and Entity Framework. I have customers making payments made to some payment categories. I want to develop a ledger where I have customer names and all the classes of payments with total payments made for any particular pay category by each customer. And I will have to group by name, year and month. And be able to filter by year, month or customerid. I have 25 payment categories.
The solution I have made is ancient- it makes use of 25 joins to the get the categories, sum the payments and assign these to a viewmodel. This runs on my developing machine alright but it fails on my server with the error
MySql.Data.MySqlClient.MySqlException: Too high level of nesting for select
Can anyone give me a better approach to achieving this goal
My Code is like below
public ActionResult LedgerReport(int? year, int? month, int? CuId)
{
var query = LedgerYrMn(year, month, CuId);
return View(query);
}
public IEnumerable LedgerYrMn(int? year, int? month, int? CuId)
{
DateTime lastmonth = DateTime.Now;
DateTime thismonth = DateTime.Now;
DateTime thismonthstart = DateTime.Now;
if (year.HasValue && month.HasValue)
{
lastmonth = (new DateTime(year.Value, month.Value, DateTime.DaysInMonth(year.Value, month.Value)).AddMonths(-1));
thismonth = (new DateTime(year.Value, month.Value, DateTime.DaysInMonth(year.Value, month.Value)));
thismonthstart = (new DateTime(year.Value, month.Value, 1));
}
var query =
(
from bk in db.Customers
// pay category 1
join tr in db.Payments
.Where(a => a.PDate <= thismonth && a.PDate >= thismonthstart && a.paycategory.Id == 1 && a.Paid=true)
on bk.CustomerID equals tr.CustomerID into trs
// pay category 2
join tr2 in db.Payments
.Where(a => a.PDate <= thismonth && a.PDate >= thismonthstart && a.paycategory.Id == 2 && a.Paid=true)
on bk.CustomerID equals tr2.CustomerID into trs2
......
etc to the 25 payment categories.
}
select new LedgerViewModel
{
food=(int?)trs.Sum(c => c.Pay) ?? 0,
fuel=(int?)trs.Sum(c => c.Pay) ?? 0
.. etc
});
return query.AsEnumerable();
}

Getting number of records by date in LINQ to SQL query even if no results

I have written the following LINQ-to-SQL to enable me to get a total number of records by day.
There are a few modifications I'd like to make to it in order to have it fit my needs. I have made various attempts but haven't been able to get it right.
I'd like to list the last 9 days, even if there were no 'opens' during this time.
I'd also like to group by Day/Month instead of just Day as I'm doing below.
An example of the output I'd love to get would be:
DateString Opens
===================
9/5 0
10/5 0
11/5 3
etc...
public List<OpensOverTimeViewModel> GetOpensOverTimeViewModel(int eId)
{
DateTime lastDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day).AddDays(-9);
DateTime currentDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day).AddDays(1);
var summary = (from p in db.Opens
where (p.ElementId == eId) && (p.Timestamp >= lastDate) && (p.Timestamp <= currentDate)
let k = new
{
Day = p.Timestamp.Day
}
group p by k into t
select new OpensOverTimeViewModel
{
DateString = t.Key.Day,
TotalOpens = t.Count(),
ElementName = ""
}).ToList();
return summary;
}
Any help on how best to tackle this would be much appreciated.
You can create a left join in code after you got the result back from the database
Put the below lines just before your return summary; line.
var allDates = from idx in Enumerable.Range(0, (currentDate - lastDate).Days)
select lastDate.AddDays(idx);
summary = (
from allDate in allDates
join su in summary on allDate.Day equals su.DateString into x
from su in x.DefaultIfEmpty()
select new OpensOverTimeViewModel
{
DateString = allDate.Day,
TotalOpens = su == null ? 0 : su.TotalOpens,
ElementName = ""
}).ToList();
To group by day/month I suggest using the whole date, replacing t.Key.Day with t.Key.Date and changing DateString into a DateTime.

Categories