Пользователь выбирает диапазон дат до недель через linq и т. Д. - PullRequest
2 голосов
/ 13 ноября 2011

У меня есть форма, которую пользователь выбирает дату начала и окончания, чтобы получить данные.Хотя пользователь выбирает дату начала и окончания, я должен показывать данные из таблицы неделя за неделей в диапазоне дат.

Моя модель проста

public class DateBetween
      public Datetime StartDate{ get;set;}
      public Datetime EndDate{ get;set;}

Я получаю список своих данных между этими датами избаза данных

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;}

Пример:

id     Date         Revenue  
1      10/11/2011   554 
2      11/10/2011   500

и т. д.

Если пользователь выберет дату, например 30.06.2011 и 10/15/2011

Я хочу показать пользователю

 Week         Date                     Avg.Revenue 
Week 1        6/30/2011-7/2/2011       587 
Week 2        7/3/2011-7/9/2011        650

...

и т. Д.

Есть ли какие-либо рекомендации относительно агрегатной функции.в linq

Ответы [ 3 ]

0 голосов
/ 13 ноября 2011

Хитрость заключалась в том, чтобы получать точную дату начала календаря для каждой недели в любом конкретном году, и для этого я использовал метод автоматизации Office DateTime.В результате появился словарь с 53 записями.После этого все стандартное LINQ группировалось и ссылалось в словаре на дату начала.

        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());

И результаты были ...

Между 01.09.2011 и 15 /01/2011 было изменено 22 файла

В период с 12.06.2011 по 18.06.2011 было изменено 11 файлов

и т. Д. И т. Д.

0 голосов
/ 14 ноября 2011

Сначала выберите объект даты с WeekOfYear, затем сгруппируйте его и ...

    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();
0 голосов
/ 13 ноября 2011

Вы можете использовать рукописный LINQ или использовать этот ответ:

Запрос LINQ, чтобы разделить упорядоченный список на подсписки смежных точек по некоторым критериям

Пример: использованиеничего кроме простого Linq и 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));
}

Для C # 3.5 и более ранних версий string.Join(", ", period)

string.Join(", ", period.Select(o => o.ToString()).ToArray())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...