查询即将到来的生日
我想问我的顾客那些生日尚未到来的顾客。查询即将到来的生日
我已经试过此查询,它 - 当然 - 失败让人赞叹:
Addresses.Where(adr => adr.DateOfBirth != null && adr.DateOfBirth.Value >
DateTime.Now).Take(15).ToList();
当然,这不能正常(不,如果你出生在未来)工作,我d想知道如何在没有一年的情况下查询我的Nullable<DateTime>
?
你能做到在同一行像这样:
context.Addresses.Where(adr => adr.DateOfBirth != null).OrderBy(adr => EntityFunctions.DiffDays(DateTime.Today, EntityFunctions.AddYears(adr.DateOfBirth, EntityFunctions.DiffYears(adr.DateOfBirth, DateTime.Today) + ((adr.DateOfBirth.Month < DateTime.Today.Month || (adr.DateOfBirth.Day <= DateTime.Today.Day && adr.DateOfBirth.Month == DateTime.Today.Month)) ? 1 : 0)))).Take(15).ToList();
或者更可读的格式:
var query = from adr in context.Addresses
where adr.DateOfBirth != null
let diffYears = EntityFunctions.DiffYears(adr.DateOfBirth, DateTime.Today)
let birthdayOccurred = adr.DateOfBirth.Month < DateTime.Today.Month || (adr.DateOfBirth.Day <= DateTime.Today.Day && adr.DateOfBirth.Month == DateTime.Today.Month)
let nextBirthdate = EntityFunctions.AddYears(adr.DateOfBirth, diffYears + (birthdayOccurred ? 1 : 0))
let daysToBirthdate = EntityFunctions.DiffDays(DateTime.Today, nextBirthdate)
orderby daysToBirthdate
select adr;
var result = query.Take(15).ToList();
尝试类似这样; (这是工作 - 我测试过)
//A mock up value for comparison (as DayOfYear not supported in Linq)
int doy = DateTime.Today.Month * 31 + DateTime.Today.Day;
var results = Addresses.Where(a => a.DateOfBirth != null)
.OrderBy(a =>
(a.DateOfBirth.Value.Month * 31 + a.DateOfBirth.Value.Day) +
(a.DateOfBirth.Value.Month * 31 + a.DateOfBirth.Value.Day > doy ? 0 : 400))
.Take(15).ToList();
这是错误的。当前日期为1月8日 - 因为7不会超过8(今天),所以不会在2月7日(这是更晚的日期)返回。 – Kamil 2013-02-27 18:12:35
我认为这仍然是错误的。当日期的任何部分更大时,它将返回数据。假设我们现在有2013年2月27日。如果生日是2013-01-28怎么办?您的代码将于当天返回,因为28大于27.您必须结合月份和日期,可能是这样:'int mmdd = month * 100 + day',然后进行比较。或者可以使用类似DayOfYear的东西,但只能与年份结合使用。 – Kamil 2013-02-27 18:27:37
上次编辑后,如果“今天”将在12月31日,而生日将在明年1月1日,则您的代码将无法使用。 – Kamil 2013-02-27 18:35:31
我不熟悉Linq,我会尝试帮助一些伪代码。
最重要的条件应该是这样的:
Date(CurrentDate.Year, DateOfBirth.Month, DateOfBirth.Day) >= CurrentDate
|| ' OR
Date(CurrentDate.Year + 1, DateOfBirth.Month, DateOfBirth.Day) >= CurrentDate
这将工作12月31日了。
备选:
// consider this as pseudocode, I didnt tested that in C#
function GetNextBirthday(DateTime DateOfBirth)
{
int yearOfNextBirthday;
int birthdayMMDD = DateOfBirth.Month*100 + DateOfBirth.Day;
int todayMMDD = CurrentDate.Month*100 + CurrentDate.Day;
if (birthdayMMDD >= todayMMDD)
{
yearOfNextBirthday = CurrentDate.Year; // this year
}
else
{
yearOfNextBirthday = CurrentDate.Year + 1; // next year
}
DateTime nextBirthday;
// you have to write this line yourself, i dont remember how to make date from Y, M, D
nextBirthday = DateFromYMD(yearOfNextBirthday, DateOfBirth.Month, DateOfBirth.Day);
return nextBirthday;
}
我不知道你能做到这一点作为一个班轮。当然没有任何清晰度。
所需的步骤是:
- 创建只包含其中 月/日今天来后出生日期排序列表。
- 创建一个有序的列表,其中只包含当天之前的月份/日期的生日。
- 将第二个列表追加到第一个列表中,您现在有一个单独的列表,按 生日排序排序。
- 在第一个15
我认为C#代码将看起来像这样(您可能需要添加一个或两个List)。
var list1 = Addresses.Where(adr => adr.DateOfBirth != null && (adr.DateOfBirth.Value.Month > DateTime.Today.Month || (adr.DateOfBirth.Value.Month == DateTime.Today.Month && adr.DateOfBirth.Value.Day >= DateTime.Today.Day))).ToList();
var list2 = Addresses.Where(adr => adr.DateOfBirth != null && (adr.DateOfBirth.Value.Month < DateTime.Today.Month || (adr.DateOfBirth.Value.Month == DateTime.Today.Month && adr.DateOfBirth.Value.Day < DateTime.Today.Day))).ToList();
var fullList = list1.Add(list2);
您无法创建今天之前和之后的生日清单。第一个原因:12月31日你的更高日期列表将为空。当某人1月1日有生日 - 他将成为下一个有生日的人,但你不会看到这个。 – Kamil 2013-02-27 18:40:20
我假设他的名单是已经出生的人(否则他们不能成为客户)。第一个列表是今天或以后生日的人。第二个列表是生日已经过去的人。通过这样结合他们,我创建了明年的生日值。 – ThatBlairGuy 2013-02-27 18:43:17
这里是我的“一个班轮”条目:
DateTime now = DateTime.Now;
var next15 =
from a in db.Addresses
where a.DateOfBirth != null
let diff = EntityFunctions.DiffSeconds(
EntityFunctions.AddYears(now, -EntityFunctions.DiffYears(a.DateOfBirth, now)),
a.DateOfBirth)
orderby diff >= 0 ? diff : diff + 366*24*60*60
select new a;
var res = next15.Take(15).ToList();
刚刚与SQL数据库测试 - 和它的作品般的魅力;)
这是同样的解决方案@Aducci但可空日期和DBFunctions,因为EntityFunctions已被弃用。
pacientes = from paciente in pacientes
where paciente.Nascimento != null
let diffYears = DbFunctions.DiffYears(paciente.Nascimento, DateTime.Today)
let birthdayOccurred = paciente.Nascimento.Value.Month < DateTime.Today.Month
|| (paciente.Nascimento.Value.Day <= DateTime.Today.Day && paciente.Nascimento.Value.Month == DateTime.Today.Month)
let nextBirthdate = DbFunctions.AddYears(paciente.Nascimento, diffYears + (birthdayOccurred ? 1 : 0))
let daysToBirthdate = DbFunctions.DiffDays(DateTime.Today, nextBirthdate)
orderby daysToBirthdate
select paciente;
鉴于*每个人*活着有一个即将到来的生日在某个时候,你想要多远?一个月?年底? – 2013-02-27 17:58:17
'拿(15)' - 接下来的15个生日。当我在12月31日运行查询时,年底可能会出现问题 – SeToY 2013-02-27 17:59:47
@Kamil在12月31日当某人在1月1日生日时,这也会失败 – SeToY 2013-02-27 18:00:47