4

誕生日がまだ来ていない顧客に質問したいのですが。

私はこのクエリを試しましたが、もちろん、息を呑むほど失敗しました。

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

もちろん、これは正しく機能しません(あなたが将来生まれた場合はそうではありません)。1Nullable<DateTime>年も経たないうちにクエリを実行する方法を知りたいですか?

4

6 に答える 6

9

次のように 1 行で実行できます。

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. 2 番目のリストを最初のリストに追加すると、誕生日順に並べ替えられた 1 つのリストが作成されます。
  4. 最初の 15 を取得します。

C# コードは次のようになると思います (リストを 1 つまたは 2 つ追加する必要があるかもしれません)。

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

これが「ワンライナー」の私のエントリーです:

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

このようなことを試してください。(これは機能しています-私はテストしました)

//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 に答える