2009-12-14 4 views
1

У меня есть таблица с несколькими записями с датой начала (PlacementDate) и датой окончания (Pulled Date). Я передаю параметры даты начала и конца даты в эту функцию, которая должна возвращать записи, которые пересекают начальную и конечную дату, прошедшие в, а также указать, сколько дней каждая запись пересекает.Linq to SQL - количество дней на перекрестке между диапазонами дат

Получение записей, которые пересекаются легко, получить количество дней пересечения диапазонов дат не так просто ... Вот что я до сих пор:

  var query = from d in db.TelemetryDevices 
        join p in db.DevicePlacements on d.TelemetryDeviceID equals p.TelemetryDeviceID 
        where d.CompanyID == companyId && d.BillingPlanID == billingPlanId 
         && (
         (p.PlacementDate <= startDate && (p.PulledDate != null ? p.PulledDate.Value : DateTime.MaxValue) >= endDate)// { start - end } 
         || (p.PlacementDate <= startDate && (p.PulledDate != null ? p.PulledDate.Value : DateTime.MaxValue) >= startDate)// { start } end 
         || (p.PlacementDate >= startDate && (p.PulledDate != null ? p.PulledDate.Value : DateTime.MaxValue) <= endDate)// start { } end 
         || (p.PlacementDate >= startDate && (p.PulledDate != null ? p.PulledDate.Value : DateTime.MaxValue) >= endDate)// start { end } 
         ) 
        select new DeviceView 
        { 
         TelemetryDeviceID = d.TelemetryDeviceID 
        }; 

Любые идеи о том, как решить это было бы весьма полезно.

+0

Прежде всего, используйте оператор нулевой Coalesce сократить код: вместо "p.PulledDate = нуль p.PulledDate.Value:? DateTime.MaxValue" использование «p.PulledDate ?? DateTime.MaxValue " – Manu

ответ

0

Посмотрите на это.

Если я неправильно понял, сообщите мне.

List<MyClass> dates = new List<MyClass>(); 
dates.Add(new MyClass { StartDate = new DateTime(2009, 01, 01), EndDate = new DateTime(2009, 01, 08) }); 
dates.Add(new MyClass { StartDate = new DateTime(2009, 01, 15), EndDate = new DateTime(2009, 01, 20) }); 
dates.Add(new MyClass { StartDate = new DateTime(2009, 01, 22), EndDate = new DateTime(2009, 01, 31) }); 
DateTime sDate = new DateTime(2009, 01, 07); 
DateTime eDate = new DateTime(2009, 01, 25); 
var result = (from d in dates 
      orderby d.StartDate 
      where !(eDate < d.StartDate || sDate > d.EndDate) 
      select new 
      { 
       Days = (d.EndDate <= eDate && d.StartDate >= sDate ? d.EndDate.Subtract(d.StartDate).Days: 
       sDate >= d.StartDate && sDate <= d.EndDate && eDate >= d.EndDate ? d.EndDate.Subtract(sDate).Days: 
       eDate >= d.StartDate && eDate <= d.EndDate && sDate <= d.StartDate ? eDate.Subtract(d.StartDate).Days: 
       eDate <= d.EndDate && sDate >= d.StartDate ? eDate.Subtract(sDate).Days : 0) 
       }).Sum(x => x.Days); 
int total = result; 
0

Когда вы делаете дату arithemtic, .Net неявно использует типы TimeSpan. Вы можете конвертировать TimeSpan в количество дней. Например:

int days = (DateTime.Now.AddDays(10) - DateTime.Now).Days; 

приведет к 10 дням. Вам просто нужно выяснить в своем запросе, какую дату использовать для сравнения (дата начала или окончания, в зависимости от того, какая из них перекрывается).

Смежные вопросы