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

Added flag prohibiting GraphDiff from ever removing collection elements ... #107

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions GraphDiff/GraphDiff.Tests/GraphDiff.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
<Compile Include="Tests\AttributeMappingBehaviours.cs" />
<Compile Include="Tests\ComplexTypeBehaviours.cs" />
<Compile Include="Tests\GuidKeyBehaviors.cs" />
<Compile Include="Tests\NeverRemoveItemsBehaviors.cs" />
<Compile Include="Tests\OwnedCollectionBehaviours.cs" />
<Compile Include="Tests\OneMemberBehaviours.cs" />
<Compile Include="Tests\OwnedEntityBehaviours.cs" />
Expand Down
86 changes: 86 additions & 0 deletions GraphDiff/GraphDiff.Tests/Tests/NeverRemoveItemsBehaviors.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RefactorThis.GraphDiff.Tests.Models;

namespace RefactorThis.GraphDiff.Tests.Tests
{
[TestClass]
public class NeverRemoveItemsBehaviors
{
[TestMethod]
public void ShouldNeverRemoveFromAssociatedCollection()
{
var node = new TestNode
{
Title = "New Node",
OneToManyAssociated = new List<OneToManyAssociatedModel>
{
new OneToManyAssociatedModel { Title = "First One" }
}
};

using (var context = new TestDbContext())
{
context.Nodes.Add(node);
context.SaveChanges();
} // Simulate detach

node.OneToManyAssociated.Remove(node.OneToManyAssociated.Single());

GraphDiffConfiguration.NeverRemoveFromCollections = true;

using (var context = new TestDbContext())
{
node = context.UpdateGraph(node, map => map.AssociatedCollection(p => p.OneToManyAssociated));
context.SaveChanges();

Assert.AreEqual(1, node.OneToManyAssociated.Count);

var nodeReloaded = context.Nodes.Include(p => p.OneToManyAssociated).Single(p => p.Id == node.Id);
Assert.IsNotNull(nodeReloaded);
Assert.AreEqual(1, nodeReloaded.OneToManyAssociated.Count);
}
}

[TestMethod]
public void ShouldNeverRemoveFromOwnedCollection()
{
var node = new TestNode
{
Title = "New Node",
OneToManyOwned = new List<OneToManyOwnedModel>
{
new OneToManyOwnedModel { Title = "Hello" },
new OneToManyOwnedModel { Title = "Hello2" },
new OneToManyOwnedModel { Title = "Hello3" }
}
};

using (var context = new TestDbContext())
{
context.Nodes.Add(node);
context.SaveChanges();
} // Simulate detach

node.OneToManyOwned.Remove(node.OneToManyOwned.First());
node.OneToManyOwned.Remove(node.OneToManyOwned.First());
node.OneToManyOwned.Remove(node.OneToManyOwned.First());

GraphDiffConfiguration.NeverRemoveFromCollections = true;

using (var context = new TestDbContext())
{
node = context.UpdateGraph(node, map => map.OwnedCollection(p => p.OneToManyOwned));
context.SaveChanges();

Assert.AreEqual(3, node.OneToManyOwned.Count);

var reloadedNode = context.Nodes.Include(p => p.OneToManyOwned).Single(p => p.Id == node.Id);
Assert.IsNotNull(reloadedNode);
Assert.AreEqual(3, reloadedNode.OneToManyOwned.Count);
}
}
}
}
6 changes: 6 additions & 0 deletions GraphDiff/GraphDiff/GraphDiffConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,11 @@ public static class GraphDiffConfiguration
/// to ensure the EF local cache has the latest state.
/// </summary>
public static bool ReloadAssociatedEntitiesWhenAttached { get; set; }

/// <summary>
/// If GraphDiff encounters an entity in a database collection that is no longer part of the graph it is
/// currently attaching, it will remove that element from the database as well unless this flag is set.
/// </summary>
public static bool NeverRemoveFromCollections { get; set; }
}
}
3 changes: 3 additions & 0 deletions GraphDiff/GraphDiff/Internal/Graph/CollectionGraphNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ private void UpdateElement<T>(IChangeTracker changeTracker, IEntityManager entit

private void RemoveElement(IChangeTracker changeTracker, object dbItem, object dbCollection)
{
if (GraphDiffConfiguration.NeverRemoveFromCollections)
return;

dbCollection.GetType().GetMethod("Remove").Invoke(dbCollection, new[] { dbItem });
changeTracker.AttachRequiredNavigationProperties(dbItem, dbItem);

Expand Down