views:

411

answers:

2

Hi I have the following code snippet.

// Here I get an entity out of an EntityCollection<TEntity> i.e ContactSet. Entity is obtained and not null.
ProjectContact obj = ((Project)projectDataGrid.SelectedItem).ContactSet
    .Where(projectContact => projectContact.ProjectId == item.ProjectId && 
           projectContact.ContactId == item.ContactId).First();

// And the next line I just check whether ContactSet contains the queried entity that i.e. obj.     
bool found = ((Project)projectDataGrid.SelectedItem).ContactSet.Contains(obj);

but found is always false. How can that be?

Thank you for the answers

A: 

This looks like it should work, Some ideas:

Does ProjectContact override Object.Equals()? Or perhaps the ContactSet implements ICollection, and there may be a bug in the implementation of ICollection.Contains()?

Matt Brunell
A: 

Matt thank you for your guidance but let me make it a bit more clear since I haven't given out the full source code.

I have three tables in my database:

Project, Contact and ProjectContact and there's a many-to-many relationship between Project and Contact table through the ProjectContact table, although ProjectContact table has some extra columns other than Project and Contact table keys, and that's why I get an extra entity called ProjectContact if I use ADO.NET entity framework's entity designer generated code.

Now at some point I get a Project instance within my code by using a linq to entities query i.e:

var item = (from project in myObjectContext.Project.Include("ContactSet.Contact") orderby project.Name select project).FirstOrDefault();

Note that ContactSet is the navigational property of Project to ProjectContact table and Contact is the navigational property of ProjectContact to Contact table.

Moreover the queried Project in question i.e. "item" has already some ProjectContacts in its item.ContactSet entity collection, and ContactSet is a standard EntityCollection implementation generated by entity designer.

On the other hand, ProjectContact overrides Equals() and GetHashCode() etc. but if I use that overriden implementation within an EqualityComparer then Project.ContactSet.Contains returns true so I'm guessing there's no problem with that but now the tricky part comes along. Assume that I have the following snippet:

using(SomeObjectContext myObjectContext = new SomeObjectContext()) {

var projectQueryable = from project in myObjectContext.Project.Include("ContactSet.Contact") orderby project.Name select project;

ObservableCollection projects = new ObservableCollection(projectQueryable.ToList());

var contactQueryable = from contact in myObjectContext.Contact select contact;

ObservableCollection contacts = new ObservableCollection(contactQueryable.ToList());

Project p = projects[0];

Contact c = contacts[0];

//Now if I execute the code below it fails.

ProjectContact projectContact = new ProjectContact();

projectContact.Contact = c;

projectContact.Project = p;

projectContact.ContactId = c.Id;

projectContact.ProjectId = p.Id;

projectContact.Role = ContactRole.Administrator; // This corresponds to the column in ProjectContact table and I do manual conversion within the partial class since EF doesn't support enums yet.

p.ContactSet.Add(projectContact); // This line might be unnecessary but just to be on the safe side.

// So now p.ContactSet does indeed contain the projectContact and projectContact's EntityState is Added as expected. But when I execute the line below without saving changes it fails.

bool result = p.ContactSet.Remove(projectContact); // result == false and projectContact is still in the p.ContactSet EntityCollection.

//Now if I execute the line below

myObjectContext.Delete(projectContact);

//Now projectContact's EntityState becomes Detached but it's still in p.ContactSet.

// Also note that if I test

bool exists = p.ContactSet.Contains(projectContact);

// It also returns false even if I query the item with p.ProjectContact.Where(...) it returns false.

}

Since everything occurs within the same ObjectContext I think I am missing something about EntityCollection.Remove(). But it seems still odd that ContactSet.Contains() returns false for an item obtained via direct Where query over ContactSet. In the end the question becomes:

How do you really Remove an item from an EntityCollection without persisting to the database first. Since a Remove() call after Add() apparently fails.

Thanks in advance for any possible insight.