How can i get date from foreach for linq - c#

I have this two codes.First one create date from today to seven days before except weekends. How can i combine second code to first one. I need to get dates from first code and use it for compare with m.CreationDate . I will use this code for : get typeid 1 and that days total book number for everydays. Thanks for answer...
public static List<DateTime> GetBusinessDays(DateTime startDate, int numDays)
{
var dates = new List<DateTime>();
var step = (numDays < 0) ? -1 : 1;
var date = startDate;
var absNumDays = Math.Abs(numDays);
while (dates.Count() < absNumDays)
{
date = date.AddDays(step);
if (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday)
continue;
dates.Add(date);
}
return dates;
}
string DateString = "";
var start = DateTime.Now;
var Dates = GetBusinessDays(start,-7);
Dates.Reverse();
foreach (var date in Dates)
{
DateString = DateString + "'" + date.ToShortDateString() + "',";
}
DateString = DateString.TrimEnd(',');
var book = from m in Connection.Db.Materials
where m.TypeId == 1 && m.25.05.2015,.ToShortDateString() == xx//need to write days here but for everyday
group m by m.TypeId into g
select new { Count = g.Count()};
get data from Dates :18.5.2015, 19.05.2015,20.05.2015,21.05.2015,22.05.2015,25.05.2015,26.05.2015.
I trying to get: m.CreationDate ==
19.05.2015 and typeid ==1 total book numbers:50
m.CreationDate ==
20.05.2015 and typeid ==1 total book numbers:15

If you toss the dates into a collection then you can use Contains in linq
var book = from m in Connection.Db.Materials
where m.TypeId == 1 && CreationDatesArray.Contains(m.CreationDate)
group m by m.TypeId into g
select new { Count = g.Count()};
Added m. as pointed out

Ok. You have date collection in Dates.
Then you perform grouping as
var book = from m in Connection.Db.Materials
where m.TypeId == 1
group m by m.CreationDate into g
select g
Then you can do
var result = Dates.Select(d => new {
Date = d,
Count = book.Where(g => g.Key == d).Count() })
And in result you get collection of dates from Dates with count from your second collection.

string DateString = "";
var start = DateTime.Now;
var Dates = GetBusinessDays(start,-7);
Dates.Reverse();
foreach (var date in Dates)
{
DateString = DateString + "'" + date.ToShortDateString() + "',";
}
DateString = DateString.TrimEnd(',');
var book = from m in Connection.Db.Materials
where m.TypeId == 1
group m by m.CreationDate into g select g;
var results = Dates.Select(d => new { Date = d.Day + "/" + d.Month + "/" + d.Year, Count = book.Where(g => g.Key.Day == d.Day && g.Key.Month == d.Month && g.Key.Year == d.Year).Count() }).ToList();
//put day, month and year. Because only dates equals with ohter dates.(I need only dates not times)
string Books = "";
foreach(var r in results)
{
Books = Books + r.Count + ',';
}
Thanks Everbody for Helping

Related

Linq Select row Where date in Current month

I need to get data from the current month.Haven't been able to find a solution that works.
This is my code, which gives me the data I need, but I get data from a whole month back, instead of from the current month we are in.
I chose the date "limit" twice with row > DateTime.Today.Addmonths(-1)
Any ideas ?
var userQuery =
from timeEntry in TimeEntries
//this displays a month back, not current month TODO: change to current month.
where timeEntry.DateEntity > DateTime.Today.AddMonths(-1)
select new {
UserName = timeEntry.User.FirstName + " " +timeEntry.User.LastName,
HoursEntered = timeEntry.HoursEntered,
User = timeEntry.User
};
var localrows = userQuery.ToList();
var grouping = localrows.GroupBy(x => x.User);
var userList = grouping.Select(q => new {
UserName = q.FirstOrDefault().UserName,
Hours = q.Sum(hr => hr.HoursEntered), //AbsenceTypeID = holiday(1) // still takes from a whole month, instead of current month.
Holiday = q.FirstOrDefault().User.Absences.Where(a => a.AbsenceTypeID == 1).Where(date => date.DateEntity > DateTime.Today.AddMonths(-1)).Count(),
});
EDIT:
Keyur patel' answer worked, though not for the bottom one.
so there i have to thank Jules for this one:
DateTime.Today.AddDays((DateTime.Today.Day -1) * -1)
Try using this:
DateTime today = DateTime.Today;
var userQuery =
from timeEntry in TimeEntries
where timeEntry.DateEntity.Month == today.Month && timeEntry.DateEntity.Year == today.Year
select new {
UserName = timeEntry.User.FirstName + " " +timeEntry.User.LastName,
HoursEntered = timeEntry.HoursEntered,
User = timeEntry.User
};
Added check for .Year since it may match with months from other years, if you have any.
Edit
As for the holiday part:
var userList = grouping.Select(q => new {
UserName = q.FirstOrDefault().UserName,
Hours = q.Sum(hr => hr.HoursEntered),
Holiday = q.FirstOrDefault().User.Absences.Where(a => a.AbsenceTypeID == 1 && a.DateEntity.Month == today.Month && a.DateEntity.Year == today.Year).Count(),
});
You can simply compare only Month part of the date like this:
timeEntry.DateEntity.Month == DateTime.Now.Month
You can use Month and Year properties of the DateTime class as follows:
var userQuery = TimeEntries
.Where (te => te.DateEntity.Month == DateTime.Today.Month && te.DateEntity.Year == DateTime.Today.Year)
.Select(timeEntry =>
new {
UserName = timeEntry.User.FirstName + " " + timeEntry.User.LastName,
HoursEntered = timeEntry.HoursEntered,
User = timeEntry.User
}
);
You can try this:
.Where(x => x.EntityDate >= new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1));

linq to retrieve name instead of id and list in descending order

can u help me to solve this.
i'm retrieving the balance of each heads, and i retrieved the balance of each heads. Now i want to list the balance in the descending order and list the name instead of h_id. i used the code
protected void account_watchlist() {
using(var context = new sem_dbEntities()) {
//ledger && head
var year = DateTime.Now.AddMinutes(318).Year;
var month = DateTime.Now.AddMinutes(318).Month;
var start = new DateTime();
if (month >= 4) {
start = new DateTime(year, 04, 01);
} else if (month < 4) {
start = new DateTime(year - 1, 04, 01);
}
var qr = (from a in context.ledgers
where a.entry_date >= start && a.entry_date < new DateTime(year, month, 1)
join b in context.heads on a.h_id equals b.h_id
group a by a.h_id into sb select new {
sb.FirstOrDefault().h_id,
totalc = sb.Sum(c => c.credit),
totald = sb.Sum(d => d.debit),
balance = sb.Sum(d => d.debit) - sb.Sum(c => c.credit)
}).ToList();
Repeater2.DataSource = qr.ToList();
Repeater2.DataBind();
}
}
You need to use group join of heads with ledgers. It will give you access both to head entity and all related ledgers (in headLedgers collection):
from h in context.heads
join l in context.ledgers.Where(x => x.entry_date >= startDate && x.entry_date < endDate)
on h.h_id equals l.h_id into headLedgers
where headLedgers.Any()
let totalc = headLedgers.Sum(l => l.credit),
let totald = headLedgers.Sum(l => l.debit),
select new {
h.h_id,
h.name,
totalc,
totald,
balance = totald - totalc,
}
I also introduced two range variables for total credit and total debit (consider better names here) to avoid calculating them second time for balance.

how to get the month name

using (DataAccessAdapter adapter = new DataAccessAdapter())
{
LinqMetaData meta = new LinqMetaData(adapter);
var datas = (from x in meta.Table
where x.DateCreated >= startDate && x.DateCreated <= endDate && x.ViaTo > 0 && !x.Cancelled
group x by new { month = x.DateCreated.Value.Month } into g
select new
{
MonthNr = g.Key,
//MonthName = ?
TotalMonthAmount = g.Sum(x => x.Amount)
});
.....
}
And startDate & endDate are valid Dates.
I only get the month number, how to get the month name for the DateCreated?
You can get the month name using this function:
CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(monthNumber);
new { month = x.DateCreated.Value.Month.ToString("MMM") }
I think you are asking about Month property. Check this:
using System;
class Program
{
static void Main()
{
DateTime now = DateTime.Now;
//
// Write the month integer and then the three-letter month.
//
Console.WriteLine(now.Month); //outputs 5
Console.WriteLine(now.ToString("MMM")); //outputs May
}
}

Linq group by month/year with empty months for past 12 months

How would I get this query to get the monthly count data for the past 12 months? I don't want to hard code the range, I want to use the current date DateTime.Now and get all the data for the past 12 months from that. I am trying to avoid adding a calendar table to the database and do this just using LINQ.
Some months might not have any data but I still need a count of 0 for those.
For example. If my data contains
Date Count
12/2/2013, 4
10/1/2014, 1
11/5/2014, 6
The results should be, using the current date of 11/9/2014
11/2013, 0
12/1013, 4
1/2014, 0
2/2014, 0
3/2014, 0
4/2014, 0
5/2014, 0
6/2014, 0
7/2014, 0
8/2014, 0
9/2014, 0
10/2014, 1
11/2014, 6
I can't get it to work. I think it's how I'm using Range but I'm not sure.
TimeSpan ts = new TimeSpan(365, 0, 0, 0);
DateTime yearAgo = DateTime.Now.Subtract(ts);
var changesPerYearAndMonth =
from year in Enumerable.Range(yearAgo.Year, 1)
from month in Enumerable.Range(1, 12)
let key = new { Year = year, Month = month }
join revision in list on key
equals new { revision.LocalTimeStamp.Year,
revision.LocalTimeStamp.Month } into g
select new { GroupCriteria = key, Count = g.Count() };
I have modified the answer from this this link as a starting point.
Linq: group by year and month, and manage empty months
I just found this article that is the same question but unanswered
Linq - group by datetime for previous 12 months - include empty months
To get the past twelve months, use
var now = DateTime.Now;
var months = Enumerable.Range(-12, 12)
.Select(x => new {
year = now.AddMonths(x).Year,
month = now.AddMonths(x).Month });
To be safe you should first move 'now' to the start of the month to avoid any end-of-month effects with AddMonth.
var now = DateTime.Now;
now = now.Date.AddDays(1-now.Day);
Complete example:-
var list = new [] {
new { LocalTimeStamp = DateTime.Parse("12/2/2013"), count = 4},
new { LocalTimeStamp = DateTime.Parse("10/1/2014"), count = 1 },
new { LocalTimeStamp = DateTime.Parse("11/5/2014"), count = 6}
};
var now = DateTime.Now;
now = now.Date.AddDays(1-now.Day);
var months = Enumerable.Range(-12, 13)
.Select(x => new {
year = now.AddMonths(x).Year,
month = now.AddMonths(x).Month });
var changesPerYearAndMonth =
months.GroupJoin(list,
m => new {month = m.month, year = m.year},
revision => new { month = revision.LocalTimeStamp.Month,
year = revision.LocalTimeStamp.Year},
(p, g) => new {month = p.month, year = p.year,
count = g.Sum(a => a.count)});
foreach (var change in changesPerYearAndMonth)
{
Console.WriteLine(change.month + " " + change.year +" " + change.count);
}
You don't need a 3-way join, you just need to filter your data before grouping.
1) Query expression syntax
// since your list item type was not posted, anyway same access as your LocalTimeStamp property
list = new List<DateTime>();
DateTime aYearAgo = DateTime.Now.AddYears(-1);
var dateslastYear = from date in list
where date > aYearAgo
group date by new { date.Year, date.Month } into g
select new { GroupCriteria = g.Key, Count = g.Count() };
2) Chained
dateslastYear = list.Where (d=>d>aYearAgo)
.GroupBy (date=>new{date.Year, date.Month });
3) If you want grouping by year/month pairs, including records of not existent entries, and also omitting those pairs that are older than a year occurring with the joined Enumerable.Range call:
var thisYearPairs = from m in Enumerable.Range(1, DateTime.Now.Month)
select new { Year = DateTime.Now.Year, Month = m };
var lastYearPairs = from m in Enumerable.Range(DateTime.Now.Month, 12 - DateTime.Now.Month + 1)
select new { Year = DateTime.Now.Year - 1, Month = m };
var ymOuter = from ym in thisYearPairs.Union(lastYearPairs)
join l in list on new { ym.Year, ym.Month } equals new { l.Year, l.Month } into oj
from p in oj.DefaultIfEmpty()
select new { a = ym, b = p == null ? DateTime.MinValue : p };
var ymGroup = from ym in ymOuter
group ym by ym into g
select new { GroupCriteria = g.Key.a, Count = g.Key.b == DateTime.MinValue ? 0 : g.Count() };
You are taking the range for the 12 months of last year only but you actually want the last twelve months.
You can do this using a Enumerable.Range and the AddMonths method:
var changesPerYearAndMonth =
from month in Enumerable.Range(0, 12)
let key = new { Year = DateTime.Now.AddMonths(-month).Year, Month = DateTime.Now.AddMonths(-month).Month }
join revision in list on key
equals new
{
revision.LocalTimeStamp.Year,
revision.LocalTimeStamp.Month
} into g
select new { GroupCriteria = key, Count = g.Count() };
public int YearDiff(DateTime a, DateTime b)
{
return (int) Math.Floor((a.Year + a.Month / 100.0 + a.Day / 10000.0) - (b.Year + b.Month / 100.0 + b.Day / 10000.0));
}

User selected date range to weeks via linq etc

I have a form which user select start and end date to get data.
Although user select start and end date i have to show data from table week by week in date range.
My model is simple
public class DateBetween
public Datetime StartDate{ get;set;}
public Datetime EndDate{ get;set;}
I get list of my datas between these dates from database
IList<Revenue> datas = DB.CreateCrateria(typeof(Revenue))
.Add(Restrictions.Bt("Date", model.startDate, model.endDate))
.List<Revenue>();
public class Revenue
public int Id{ get;set;}
public double Revenue { get;set;}
public Datetime RevenueDate{ get;set;}
Example:
id Date Revenue
1 10/11/2011 554
2 11/10/2011 500
etc
If user select date like 6/30/2011 and 10/15/2011
I want to show to user
Week Date Avg.Revenue
Week 1 6/30/2011-7/2/2011 587
Week 2 7/3/2011-7/9/2011 650
...
etc
Is there any recommendation doing with aggregate funct. in linq
You could use a handwritten LINQ or use this answer:
LINQ query to split an ordered list into sublists of contiguous points by some criteria
Example: using nothing else than plain Linq and DateTime/Calendar:
var rnd = new Random();
var data = Enumerable.Range(1,100).Select(i => DateTime.Now.AddDays(rnd.Next(-91000,91000)/24));
var calendar = CultureInfo.CurrentCulture.Calendar;
Func<DateTime, int> twoWeeks = dt => (dt.Year * 100) + 2 * (calendar.GetWeekOfYear(dt, CalendarWeekRule.FirstFullWeek, DayOfWeek.Sunday) / 2);
var by2weeks = data.GroupBy(twoWeeks);
foreach (var period in by2weeks.OrderBy(g => g.Key))
{
Console.WriteLine("{0}: {1}", period.Key, string.Join(", ", period));
}
For C# 3.5 and earlier string.Join(", ", period)
string.Join(", ", period.Select(o => o.ToString()).ToArray())
The trick was getting the exact calendar start date for each week in any given year, and for that I looped on DateTime's Office Automation method. Doing that produced a Dictionary with 53 entries. After that, it was all standard LINQ grouping and referencing into the dictionary for the start date.
Calendar cal = Calendar.ReadOnly(CultureInfo.CurrentCulture.Calendar);
StringBuilder sb = new StringBuilder();
DirectoryInfo rdi = new DirectoryInfo(Root); // get all files in the root directory
List<FileInfo> allfis = rdi.GetFiles("*", SearchOption.AllDirectories).ToList();
var a = allfis.GroupBy(q=>cal.GetYear(q.LastWriteTime));
foreach (var b in a.Where(q=>q.Key==2011)) // this year only
{
double yearStartOaDate = new DateTime(b.Key, 1, 1).ToOADate();
double yearEndOaDate = yearStartOaDate + 365;
// get exact start dates for each week
Dictionary<int, DateTime> weekStartingDates = new Dictionary<int, DateTime>();
while (yearStartOaDate <= yearEndOaDate)
{
DateTime dt = DateTime.FromOADate(yearStartOaDate);
int ww = cal.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
if(!weekStartingDates.ContainsKey(ww))
{
weekStartingDates.Add(ww, dt);
}
yearStartOaDate += ww == 1 ? 1 : 7;
}
var c = b.GroupBy(q => cal.GetWeekOfYear(q.LastWriteTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday)).OrderBy(q=>q.Key);
foreach(var d in c)
{
sb.AppendLine("Between " + weekStartingDates[d.Key].ToShortDateString() + " and " + weekStartingDates[d.Key].AddDays(6).ToShortDateString() + " there were " + d.Count() + " files modified");
}
}
File.WriteAllText("results.txt", sb.ToString());
And the results were...
Between 09/01/2011 and 15/01/2011 there were 22 files modified
Between 12/06/2011 and 18/06/2011 there were 11 files modified
etc etc.
First Select date object with WeekOfYear then group on it and ...
var result = datas.Select(p => new
{
week = EntityFunctions.DiffDays(EntityFunctions.CreateDateTime(p.Date.Year, 1, 1, 0, 0, 0), p.Date.Value).Value / 7,
Date= p.Date,
Revenue= p.Revenue
}).GroupBy(p => p.week)
.Select(p => new
{
week=p.Key,
Date=string.Format("{0:M/d/yyyy}",p.Min(q=>q.Date))+"-"+string.Format("{0:M/d/yyyy}",p.Max(q=>q.Date))
Revenue=p.Average(q=>q.Revenue)
}).ToList();

Categories