4

我想向我的客户查询那些生日还没到的客户。

我试过这个查询,它 - 当然 - 失败了:

Addresses.Where(adr => adr.DateOfBirth != null && adr.DateOfBirth.Value >
DateTime.Now).Take(15).ToList();

当然这不能正常工作(如果你出生在未来就不行),我想知道如何在Nullable<DateTime>没有一年的情况下查询我的?

4

6 回答 6

9

您可以像这样在一行中执行此操作:

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();
于 2013-02-27T18:53:10.370 回答
1

我不确定您是否可以将其作为单线来执行。当然没有任何程度的清晰度。

所需的步骤是:

  1. 创建一个仅包含今天之后的月/日的生日的有序列表。
  2. 创建一个仅包含今天之前的月/日的生日的有序列表。
  3. 将第二个列表附加到第一个列表,您现在有一个列表,按生日顺序排序。
  4. 拿前15个。

我认为 C# 代码看起来像这样(您可能需要添加一个或两个列表。)

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);
于 2013-02-27T18:23:54.750 回答
0

尝试这样的事情;(这是有效的 - 我已经测试过)

//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();
于 2013-02-27T18:10:42.207 回答
0

我不熟悉 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;
}
于 2013-02-27T18:10:54.457 回答
0

这是我对“一个班轮”的条目:

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 数据库测试过——它就像魅力一样工作;)

于 2013-02-27T18:58:04.393 回答
0

这是与@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;
于 2017-03-09T17:52:29.503 回答