3

I am using the entity framework 4 with edmx files and POCOs within an asp.net mvc application.

First of all I have a person class which is mapped to a table in the database.

public class Person
{
    public Int32 ID{get;set;}
    public string Name{get;set;}
    public Int32? ParentID{get;set;}
}

Then in my service layer I have the following function to retrieve all persons. If a parentID is supplied the persons retrieved will be the ones with that parentID:

public List<Person> Get(int? parentPersonID = null)
{
    var persons = Repository().GetAll(c => c.ParentID == parentPersonID);
}

Finally, the Repository() function returns an IRepository<Person> which contains the method:

public IQueryable<TModel> GetAll(Expression<Func<TModel, bool>> predicate = null)
{
    var result = ObjectSet.AsQuaryable(); //ObjectSet is a ObjectSet<Person> instance
    if (predicate != null)
        result = result.Where(predicate);
    return result;
}

Now, the problem is that if I pass null as parentPersonID to the service layer, so as Get(null). Enumeration yields no results. However if I modify the service layer code to:

public List<Person> Get(int? parentPersonID = null)
{
    var persons = Repository().GetAll(null);
}

everything works as expected.

Any ideas why is that?

EDIT: If i replace the service layer function code with:

var persons = Repository().GetAll(c => c.ParentID.Equals(parentPersonID));

instead of:

var persons = Repository().GetAll(c => c.ParentID == parentPersonID);

it works as expected - the first line retrieves records from the DB whereas the second one does not. I am still curious as to what is the difference in the Equals() and == in this case.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
sTodorov
  • 5,435
  • 5
  • 35
  • 55

1 Answers1

2

I suspect it's to do with how equality is being handled. Try this:

public List<Person> Get(int? parentPersonID = null) {
    var persons = Repository().GetAll(parentPersonID == null ? 
          c => !c.ParentID.HasValue :                
          c => c.ParentID == parentPersonID);
    ... 
}

This will change the predicate to be an explicit nullity check when you pass in a parentPersonID of null, rather than making it just match the value you've passed in. There may well be a more elegant way of expressing it, but it's worth at least trying that to start with.

(I assume that if you specify a parentPersonID of null you want to get all the people with a null parentPersonID, not just all the people... that would be a different change.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • your assumption is correct, yes. Furthermore, the explicit check works (same outcome as Equals()). I am curious though at how exactly the equality with variables with the value null is handled. Also found this one subsequently: http://stackoverflow.com/questions/682429/how-can-i-query-for-null-values-in-entity-framework – sTodorov Jun 03 '11 at 06:51
  • @sTodorov: Yes, my workaround is like that but slightly earlier - so you end up with a simple predicate either way. – Jon Skeet Jun 03 '11 at 06:52