2013-02-14 10 views
5

Przeprowadzam zapytanie (w bazie danych Northwind) w dniu urodzenia pracowników i chcę uzyskać ich wiek. Jak mogę to zrobić?Zapytanie LINQ na temat daty urodzenia, aby uzyskać wiek

private void Form1_Load(object sender, EventArgs e) 
    { 
     using (NorthWindDataContext dataContext = new NorthWindDataContext()) 
     { 
      DateTime today = DateTime.Today; 

      var q1 = from z in dataContext.Employees 
        select new 
        { 
         z.FirstName, 
         today-z.BirthDate <---- problem here 
        }; 

      dataGridView1.DataSource = q1; 

     } 
    } 

w mojej ostatecznej siatce chcę kolumnę wieku.

urodzin = 29/05/1969 (przykład)

+0

Na czym polega problem? – V4Vendetta

Odpowiedz

9

To może być trudne, ponieważ trzeba upewnić się, że urodziny zdał w tym roku, w przeciwnym razie twój wiek będzie się o jeden.

var query = from e in dataContext.Employees 
      //get the difference in years since the birthdate 
      let years = DateTime.Now.Year - e.BirthDate.Year 
      //get the date of the birthday this year 
      let birthdayThisYear = e.BirthDate.AddYears(years) 
      select new 
      { 
       //if the birthday hasn't passed yet this year we need years - 1 
       Age = birthdayThisYear > DateTime.Now ? years - 1 : years 
      }; 

Robienie tego w ten sposób ma tę zaletę, że oblicza wiek w wygenerowanym zapytaniu SQL. Oznacza to, że nie trzeba wykonywać iteracji po zestawie wyników po stronie klienta, aby obliczyć wiek.

W przypadku jesteś zainteresowany, będzie produkować następujące SQL:

-- Region Parameters 
DECLARE @p0 Int = 2013 
DECLARE @p1 DateTime = '2013-02-14 09:08:46.413' 
DECLARE @p2 Int = 1 
-- EndRegion 
SELECT [t2].[value] AS [years], [t2].[value2] AS [birthdayThisYear], 
    (CASE 
     WHEN [t2].[value2] > @p1 THEN [t2].[value] - @p2 
     ELSE [t2].[value] 
    END) AS [Age] 
FROM (
    SELECT [t1].[value], DATEADD(YEAR, [t1].[value], [t1].[BirthDate]) AS [value2] 
    FROM (
     SELECT [t0].[BirthDate], @p0 - DATEPART(Year, [t0].[BirthDate]) AS [value] 
     FROM [Employees] AS [t0] 
     ) AS [t1] 
    ) AS [t2] 
+0

Świetna odpowiedź. Po dodaniu mojego kodu, do tej pracy, zamieniłem wiersz "e.BirthDate.AddYears (years)" z DbFunctions.AddYears (e.BirthDate, lata) i wszystko idzie dobrze –

0
var q1 = from z in dataContext.Employees 
      select new 
     { 
      z.FirstName, 
      z.BirthDate, 
      Age = DateTime.Now.Year - z.BirthDate.Year 
     }; 
+0

To nie byłem ja, ale domyślam się, że to jest minus, a nie myślnik. –

+0

@DoctorJones tak - po dalszej inspekcji zdałem sobie sprawę, że dzisiaj ogłosił zmienną. Trochę za wcześnie :-) –

6

Tworzenie anonimowy obiekt, który ma 3 właściwości: FirstName, Age i BirthDate (to jest potrzebne do sprawdzenia, czy pracownik urodziny zdał w tym roku, czy nie) .

var q1 = (from z in dataContext.Employees 
    select new 
    { 
     FirstName = z.FirstName, 
     Age = today.Year - z.BirthDate.Year, 
     BirthDate = z.BirthDate 
    }).ToList(); 

q1.ForEach(x => if (x.BirthDate > today.AddYears(-x.Age)) { x.Age--; }); 

Według komentarzy (które są po prawej) należy również sprawdzić, czy BirthDate zdał czy nie, więc po wybraniu danych trzeba uruchomić sprawdzenia tego.

+0

Jak to się zmieni przed i po przyjęciu urodzin? – bendataclear

+1

To nie zadziała, jeśli dzień urodzenia nie minął jeszcze w tym roku. Poda on wiek o jeden rok za wysoki w tej sytuacji. –

+0

Ma to wadę konieczności określenia wieku po stronie klienta z powodu foreach. Sprawdź moją odpowiedź na rozwiązanie, które oblicza wiek w SQL. –

1

Musisz nazwie własność, coś takiego:

private void Form1_Load(object sender, EventArgs e) 
{ 
    using (NorthWindDataContext dataContext = new NorthWindDataContext()) 
    { 
     DateTime today = DateTime.Today; 

     var q1 = from z in dataContext.Employees 
       select new 
       { 
        Name = z.FirstName, 
        Age = today - z.BirthDate 
       }; 

     dataGridView1.DataSource = q1; 

    } 
} 
1
var temp = from o in dataContext.Employees 
    select new 
    { 
     FirstName = o.FirstName, 
     Age = DateTime.Now.Year - z.BirthDate.Year -1 
    }; 
Powiązane problemy