Question

I have an object defined as such:

public  class QuestionSetAssignee
{
    [Required]
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    public virtual ICollection<QuestionSet> QuestionSets { get; set; }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

    public override bool Equals(Object obj)
    {
        if (obj == null)
        {
            return false;
        }

        QuestionSetAssignee qsa = obj as QuestionSetAssignee;

        return Id == qsa.Id;
    }
}

The following statement:

QuestionSetAssignees.Contains(director)

in

public bool isEditable()
{
    ApplicationDbContext db = new ApplicationDbContext();
    QuestionSetAssignee director = db.QuestionSetAssignees.Find((int)QuestionSetAssigneeEnum.Director);

    if (Conference.AcceptingDirectorApplications && QuestionSetAssignees.Contains(director))
    {
        return false;
    }

    return true;
}

returns false, when as far as i can tell is should return true. (Note: Conference.AcceptingDirectorApplications returns true)

In case it's not immediately clear, the director object and the HashSet objects come through as DynamicProxies (due to EF and object hierarchy).

Here is the director object:

enter image description here
(Click for larger view)

and here is the QuestionSetAssignees object:

enter image description here
(Click for larger view)

I do not have control over the type of QuestionSetAsignees as it is supplied by EF 6 (it is declared as an ICollection in the model. This also means I am unable to provide a compare object (well, as far as I know). All I want to do is be able to compare two QuestionSetAsignee objects. I have also tried implementing IEquatable, but that did not work.

Was it helpful?

Solution

The problem is it is turning your Contains() in to a SQL call so no matter what you put in Equals and GetHashCode() it won't matter because the database you are connecting to does not use them for testing equality (This is why "This" == "this" will return true when working with entity framework on a database who's collation is not case sensitive).

The "quick and dirty" way to fix it is to realize the collection in memory and then do the .Contains

QuestionSetAssignees.AsEnumerable().Contains(director))

But that will not give you very good performance. You will likely need to approach this query a different way so the SQL behaves like you want it to.

I think the following may work, but please test it and let me know if it does not, I will remove it.

QuestionSetAssignees.Select(assignee => assignee.Id).Contains(director.Id)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top