Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Navigation Collection Cleared after first SaveChanges #16483

Closed
fromberg100 opened this issue Jul 6, 2019 · 5 comments
Closed

Navigation Collection Cleared after first SaveChanges #16483

fromberg100 opened this issue Jul 6, 2019 · 5 comments

Comments

@fromberg100
Copy link

fromberg100 commented Jul 6, 2019

Hi,

I am having an issue when updating a collection of an existing entity. Everything is OK when I call _dbContext.SaveChanges() the first time.

Before calling SaveChanges(), all items in collection are marked as EntityState.Added which is Ok, and when I call SaveChanges() the items are inserted into the database.

But after that, the navigation collection is cleared and its items are marked as EntityState.Deleted, and if I call SaveChanges() again they are deleted from the database.

See structure below (simplified):

public class Parent
{

    public Parent()
    {
        this.Children = new List<ParentChild>();
    }

    public int Id { get; set; }

    public string Name { get; set; }

    public virtual IList<ParentChild> Children { get; set; }
}

public class Child
{
    public int Id { get; set; }

    public string Name { get; set; }
}

public class ParentChild
{
    public int ParentId { get; set; }

    public int ChildId { get; set; }

    public int SortOrder { get; set; }

    public virtual Parent Parent { get; set; }

    public virtual Child Child { get; set; }
}

The update method is as follows:

int parentId = 100;

Parent entity = _dbContext.Parents
    .Include(x => x.Children)
    .Where(x => x.Id == parentId)
    .FirstOrDefault()
    ;


entity.Children = new List<ParentChild>
{
    new ParentChild
    {
        ParentId = parentId,
        ChildId = 20,
        SortOrder = 1
    },
    new ParentChild
    {
        ParentId = parentId,
        ChildId = 25,
        SortOrder = 2
    },
    new ParentChild
    {
        ParentId = parentId,
        ChildId = 30,
        SortOrder = 3
    }
};

_dbContext.SaveChanges();

//some extra updates here

_dbContext.SaveChanges();

Am I doing something wrong?

@ajcvickers
Copy link
Member

@fromberg100 The update method does this:

  • Loads all existing children
  • Removes all existing children from navigation (because the collection is replaced) and replaces them with three new children
  • SaveChanges will now delete all the existing children and insert all new children

If that's not your intention, then that might be the issue. Otherwise, please post a small, runnable project/solution or complete code listing that demonstrates the behavior you are seeing.

@fromberg100
Copy link
Author

I was not clearing the collection, however, I tried and also got the same results.

I missed to include that I override Equals:

public class ParentChild
{
    public int ParentId { get; set; }

    public int ChildId { get; set; }

    public int SortOrder { get; set; }

    public virtual Parent Parent { get; set; }

    public virtual Child Child { get; set; }

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

        var other = (ParentChild)obj;

        if (!Object.Equals(this.ParentId, other.ParentId))
            return false;
        if (!Object.Equals(this.ChildId, other.ChildId))
            return false;

        return true;
    }
}

When I do not override Equals, then it works ok. I believe this is related to issue #16161

@ajcvickers
Copy link
Member

@fromberg100 Please post a small, runnable project/solution or complete code listing that demonstrates the behavior you are seeing.

@fromberg100
Copy link
Author

fromberg100 commented Jul 10, 2019

please find solution enclosed. Please read carefully the comments I wrote specifically on top of method SetSameChildren on file Program.cs (line no. 52)

If there is anything unclear, please let me know.

UpdateCollection.zip

@ajcvickers
Copy link
Member

@fromberg100 Confirmed this is a duplicate of #16161. However, note that defining Equals and GetHashCode in this way goes against best practice for .NET code since it depends on mutable state which makes the hashing unstable. See #15687 (comment)

ajcvickers added a commit that referenced this issue Jul 15, 2019
Issue #16483 which is already fixed in 3.0
Issue #16546 which I thought might be fixed, but isn't
ajcvickers added a commit that referenced this issue Jul 15, 2019
Issue #16483 which is already fixed in 3.0
Issue #16546 which I thought might be fixed, but isn't
ajcvickers added a commit that referenced this issue Feb 13, 2020
Issue #16483 which is already fixed in 3.0
Issue #16546 which I thought might be fixed, but isn't
ajcvickers added a commit that referenced this issue Feb 15, 2020
Issue #16483 which is already fixed in 3.0
Issue #16546 which I thought might be fixed, but isn't
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants