How to get all the birthdays of today?

 ̄綄美尐妖づ 提交于 2019-12-02 06:12:46
Peter Majeed

Anytime a vendor writes a four part blog series on how to do something as simple as finding a birthday (as Microsoft did in 2007), you have to know this won't be simple. So far as I can tell, this hasn't updated since then.

So you have limited options:

  1. Make new fields called something like new_birthmonth and new_birthday that's updated every time a contact is created or updated via a plugin, and then query on those int fields.
  2. Using Dynamic Linq, construct an OR clause in your WHERE clause that checks to see if the birthday falls in a reasonable range of years (say, 140 for the long-livers) (code below).
List<string> birthdays = new List<string>(); //will contain list of OR clauses

//makes sure no CRM unsupported dates are passed (less than 1/1/1900)
for (int i = Math.Min(140, DateTime.Today.Year - 1900); i > -1; i--) 
{
    //adds a different date per year
    birthdays.Add
    (
        string.Format
        (
            //DateTimes are stored in UTC
            "BirthDate = DateTime.Parse(\"{0}\")",
            DateTime.Today.ToUniversalTime().AddYears(-i)
        )
    );
}

//completes the correct dynamic linq OR clause
string birthdayList = string.Join(" OR ", birthdays);

var getBirthdays = orgContext.CreateQuery<Xrm.Contact>()
    .Where(c => c.BirthDate != null)
    .Where(birthdayList)
    .ToList();

I solved my problem based on the example of "Peter Majeed" and using "LinqKit"!

var predicate = PredicateBuilder.False<Contact>();
for (int i = Math.Min(140, DateTime.Today.Year - 1900); i > -1; i--)
{
    DateTime cleanDateTime = new DateTime(DateTime.Today.AddYears(-i).Year, DateTime.Today.AddYears(-1).Month, DateTime.Today.AddYears(-i).Day);
    predicate = predicate.Or(p => p.BirthDate == cleanDateTime.ToUniversalTime());
}
var getBirthdays = (from c in orgContext.CreateQuery<Contact>().AsExpandable().Where(predicate)
                     select c).ToList();

The above query gave me the correct result! Thx to all who helped me!

If c.BirthDate is nullable, you have to convert it to a datetime first:

var getBirthdays = orgContext.CreateQuery<Contact>()
                             .Where(c => c.BirthDate != null && 
                                     (Convert.ToDateTime(c.BirthDate).Month == 
                                        DateTime.Now.Month) && 
                                      Convert.ToDateTime(c.BirthDate).Day == 
                                        DateTime.Now.Day))
                             .ToList();

You could fetch this info with a Query, if that is possible in your situation?

//set up the condition + filter
var ce = new Microsoft.Xrm.Sdk.Query.ConditionExpression();
ce.Operator = Microsoft.Xrm.Sdk.Query.ConditionOperator.LastXDays;
ce.AttributeName = "birthdate";
ce.Values.Add(30);

var fe = new Microsoft.Xrm.Sdk.Query.FilterExpression();
fe.AddCondition(ce);

//build query
var query = new Microsoft.Xrm.Sdk.Query.QueryExpression();
query.EntityName = "contact";
query.Criteria.AddFilter(fe);

//get results
var results = CrmHelperV5.OrgProxy.RetrieveMultiple(query);

//if you want early bound entities, convert here.
var contacts = new List<Contact>();
foreach(var result in results.Entities)
{
    contacts.Add(result.ToEntity<Contact>());
}

You may want to investigate the other operators for the filters + conditions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!