我想問我的顧客那些生日尚未到來的顧客。查詢即將到來的生日
我已經試過此查詢,它 - 當然 - 失敗讓人讚歎:
Addresses.Where(adr => adr.DateOfBirth != null && adr.DateOfBirth.Value >
DateTime.Now).Take(15).ToList();
當然,這不能正常(不,如果你出生在未來)工作,我d想知道如何在沒有一年的情況下查詢我的Nullable<DateTime>
?
我想問我的顧客那些生日尚未到來的顧客。查詢即將到來的生日
我已經試過此查詢,它 - 當然 - 失敗讓人讚歎:
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;
}
我不知道你能做到這一點作爲一個班輪。當然沒有任何清晰度。
所需的步驟是:
我認爲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