0

I want to show list of people whose birthdays are in coming 15 days. I have below dates in my table column:

LET ME MORE CLEAR MY QUESTION

BELOW IS MY EMPLOYEE TABLE COLUMNS

EMP_ID  |EMP_TYPE   |EMP_USERNAME       |EMP_DOB
======= |========== |===============    |==================
1       |ADMIN      |ELENA GILBERT      |1993-02-19
2       |EMPLOYEE   |KATHERINE PIERCE   |1993-03-19
3       |EMPLOYEE   |STEFAN SALVATORE   |1993-04-19
4       |EMPLOYEE   |DAMON SALVATORE    |1993-05-19
5       |EMPLOYEE   |JEREMY GILBERT     |1993-05-20

Now I just want to show upcoming birthdays in 15 days. Below I created a custom class in which I set two properties:

public class Birthday
{
   public string Name { get; set; }
   public DateTime date { get; set; }
}

Below is my web method which return me a list from which I want just Emp_Username and Emp_DOB which upcoming within 15 days.

[WebMethod]
public static List<Birthday> getBirthday()
{
   var slist = new List<Birthday>();
   var db = new BLUEPUMPKINEntities();
   var query = (from emp in db.Employees
   let BirthdayDiff = (new DateTime(DateTime.Now.Year,
                      emp.EMP_DOB.Value.Month, emp.EMP_DOB.Value.Day) -                                                                                                         DateTime.Now).TotalDays where BirthdayDiff >= 0 && BirthdayDiff <= 15
                      select new Birthday { Name = emp.EMP_USERNAME, date = Convert.ToDateTime(emp.EMP_DOB) });
                      return slist.ToList();
    }

Problem is my above code is not working and not showing any errors in de-bugging.

Ahmer Ali Ahsan
  • 5,636
  • 16
  • 44
  • 81

4 Answers4

2

You should change your query to something like this and then return it:

[WebMethod]
public static List<Employee> getBirthday()
{
    var db = new BLUEPUMPKINEntities();
    const int dateOffset = 15;

    var today = DateTime.Today;
    var maxDate = DateTime.Today.AddDays(dateOffset);

    return (from emp in db.Employees
            where emp.EMP_DOB.Value >= today
            where emp.EMP_DOB.Value <= maxDate
            select emp).ToList();
}
Peroxy
  • 646
  • 8
  • 18
1

There are at least three issues in your code.


Firstly, this line can potentially produce incorrect results:

let BirthdayDiff = (new DateTime(DateTime.Now.Year, emp.EMP_DOB.Value.Month, emp.EMP_DOB.Value.Day) - DateTime.Now).TotalDays

Note that you use the current time to produce year

DateTime.Now.Year

And consider the following case:

Now is 25-Dec-15 and One of your Employee is having birthday in 3-Jan-16. According to the calculation, you would produce DateTime with value of 3-Jan-15 for your Employee and you minus it with DateTime.Now and thus you will get value < -300 in total days.


Secondly, don't use DateTime.Now more than once in a single query, because the result of the subsequent DateTime.Now may be different from the first one. Use only once:

DateTime now = DateTime.Now; //and then just use now

Or even better, to remove all hours and minutes discrepancy:

DateTime today = DateTime.Today;

And lastly, you never return the result of the query, but only an empty List.

Note that you define:

var slist = new List<Employee>();

And the query:

var db = new BLUEPUMPKINEntities();
var query = from emp in db.Employees
            let BirthdayDiff = (new DateTime(DateTime.Now.Year, emp.EMP_DOB.Value.Month, emp.EMP_DOB.Value.Day) - DateTime.Now).TotalDays
            where BirthdayDiff >= 0 && BirthdayDiff <= 15
            select emp;

But you neither relate your slist with query nor return the query itself. Thus, you always get nothing, because slist is always an empty, new List.


Minor Edit: change from db to db.Employees and adding ToList()

Correct three of them and you have a safe way to do get what you want (Note: beware of leap year):

[WebMethod]
public static List<Employee> getBirthday()
{
    var slist = new List<Employee>();
    var db = new BLUEPUMPKINEntities();
    var today = DateTime.Today; //2.
    return (from emp in db.Employees
            let BirthdayDiff = (new DateTime(today.Year, emp.EMP_DOB.Value.Month, emp.EMP_DOB.Value.Day) - today).TotalDays
            let TrueBirthdayDiff = BirthdayDiff >= 0 ? BirthdayDiff : BirthdayDiff + 365 + Convert.ToInt32(DateTime.IsLeapYear(now.Year)) //1, 3 and leap year
            where TrueBirthdayDiff >= 0 && TrueBirthdayDiff <= 15
            select emp).ToList();
}
Ian
  • 30,182
  • 19
  • 69
  • 107
  • It shows me an error of `Only parameterless constructors and initializers are supported in LINQ to Entities.` – Ahmer Ali Ahsan Feb 18 '16 at 06:19
  • @AhmerAliAhsan where is it returned? which line? Oh, sorry, please put `db.Employees` instead of `db` will update my code soon. – Ian Feb 18 '16 at 06:21
  • Yes I updated from my end but It shows me above error at return – Ahmer Ali Ahsan Feb 18 '16 at 06:23
  • @AhmerAliAhsan sorry, forgot to add `.ToList()`, since the return is `IEnumerable` otherwise. – Ian Feb 18 '16 at 06:24
  • @AhmerAliAhsan as for the error, there could be some reference to it: http://stackoverflow.com/questions/3571084/only-parameterless-constructors-and-initializers-are-supported-in-linq-to-entiti , http://stackoverflow.com/questions/27177561/only-parameterless-constructors-and-initializers-are-supported-in-linq-to-entiti , https://social.msdn.microsoft.com/Forums/en-US/49a23b65-cdf8-4f58-b4a0-4effbe10c1ae/linq-to-entites-parameterless-constructor-error?forum=adodotnetentityframework – Ian Feb 18 '16 at 06:31
  • @AhmerAliAhsan they basically say that you need to re-construct your `Employee` object *after* the query. As I am not sure how your `Employee` object look like, I cannot help much on this. But seeing the example from the links I posted in the comment, you can notice that first you create a kind of `new {prop1 = something, prop2 = somethingElse}` and so on for your query, and then assign them later to your newly made `Employee` object `x => new Employee(prop1 = x.prop1, prop2 = x.prop2)` and so on... – Ian Feb 18 '16 at 06:35
  • Please see my updated code. What I want and what I try. – Ahmer Ali Ahsan Feb 18 '16 at 16:01
  • @AhmerAliAhsan is that all your code? It looks quite strange to me. For instance, why there is `- select new ...`? It is *minus* and then `select new`? Also, check the first and second issue I mentioned. Seems like you may still have them, no? That is because you use current year... – Ian Feb 18 '16 at 16:07
  • @AhmerAliAhsan nevertheless, your question is much clearer now. I might be able to help further. Now, in my time zone, it is already past midnight. I need to go to sleep soon. Will try to see the question again tomorrow, if by that time there isn't any good answer yet. – Ian Feb 18 '16 at 16:09
  • Fine. You take your time. we discuss on tomorrow. – Ahmer Ali Ahsan Feb 18 '16 at 16:11
  • @AhmerAliAhsan "the code isn't working" - this is going to be the first clue, but probably it is best to also display *how* it is not working. Giving three more things will be useful: (1) input (this you already did) (2) expected output (given the input), and (3) actual output. Now, you are missing (2) and (3). – Ian Feb 19 '16 at 01:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/103926/discussion-between-ahmer-ali-ahsan-and-ian). – Ahmer Ali Ahsan Feb 19 '16 at 07:25
  • Please check my answer in below post. I got upcoming birthdays which are coming in current month and also check between in custom days. – Ahmer Ali Ahsan Feb 20 '16 at 05:34
1

By using below query I found a way to know upcoming birthdays. I don't know why folks down voted my this post.

var day = DateTime.Now.Day;
var month = DateTime.Now.Month;
            var query = (from emp in db.Employees
                     where emp.EMP_DOB.HasValue == true
                     && emp.EMP_DOB.Value.Day >= day && emp.EMP_DOB.Value.Month == month
                     select new Birthday
                     {
                         Name = emp.EMP_USERNAME,
                         date = emp.EMP_DOB.Value
                     }).ToList();

        return query;
Ahmer Ali Ahsan
  • 5,636
  • 16
  • 44
  • 81
  • No, it does not seem to be correct. :( emp.EMP_DOB.Value.Day >= day && emp.EMP_DOB.Value.Month == month this can only compare the current month, cannot get employee with next month's birthday but having day of month less than the current day. I suggest you to give more birthday samples to see whether your algorithm works or not, and take it slowly, one by one... – Ian Feb 20 '16 at 06:36
  • I just want to show coming birthdays in 15 days in current month so If I code: emp.EMP_DOB.Value.Day <= 15 && emp.EMP_DOB.Value.Month == month then I get bdays coming in 15 days. – Ahmer Ali Ahsan Feb 20 '16 at 07:16
0

You're returning an empty list...

[WebMethod]
public static IList<Employee> getBirthday()  //<-- changed signature to IList
{
    var slist = new List<Employee>();
    var db = new BLUEPUMPKINEntities();
    var query = from emp in db.Employees
                let BirthdayDiff = (new DateTime(DateTime.Now.Year,     
                emp.EMP_DOB.Value.Month, emp.EMP_DOB.Value.Day) - DateTime.Now).TotalDays
                where BirthdayDiff >= 0 && BirthdayDiff <= 15
                select emp;
    //return slist;  //<-- problem right here!
    return query.ToList();  //<-- this should fix it...!
}

If your heart and soul is really tied to that List<T>, then do this right before the return slist:

slist.AddRange(query);

HTH!

code4life
  • 15,655
  • 7
  • 50
  • 82