-
-
Notifications
You must be signed in to change notification settings - Fork 99
Description
There is a critical, silent data-corruption bug when setting navigation properties in AttachCyclicNavigationProperty
.
The issue is how the navigation property that must be fixed in child entity is found, here:
https://github.com/zzzprojects/GraphDiff/blob/master/GraphDiff/GraphDiff.Shared/Internal/Graph/GraphNode.cs#L116-L119
The logic is to look at all navigation properties in child entity, keep only navigations to the correct (Parent) type, and keep one randomly FirstOrDefault
.
If you have a complex model with multiple relations between the same entities, this might set the wrong property (it happened to us and took an entire afternoon to debug). Because there is no error, this will then corrupt your data in DB when you save, without anyone noticing -- at first 😏
AttachCyclicNavigationProperty
is for example called when updating a many-to-one collection.
So the following example has a good chance of corrupting the data:
class Parent {
public int Id { get; set; }
// Assume you map Children to the reverse property Inverse
public ICollection<Child> Children { get; set; }
}
class Child {
// Child has multiple navigation properties to Parent
// Assume they have no reverse-mapping, except Inverse, which is the reverse navigation of Children.
public int aId { get; set; }
public Parent A { get; set; }
public int bId { get; set; }
public Parent B { get; set; }
public int inverseId { get; set; }
public Parent Inverse { get; set; }
}
// Code likely to corrupt data
var child = new Child();
var parent = new Parent { Children = new List { child } };
db.UpdateGraph(parent, map => map.AssociatedCollection(p => p.Children));
// When updating p.Children, GraphDiff will look for a reverse navigation property on Child,
// whose type is Parent.
// Because there are 3 such navigation properties, it'll pick and set the 1st one,
// which is likely to not be the right one.
// So it is likely that at this point in code, `parent` was incorrectly set into child.A
I guess the fix is that AttachCyclicNavigationProperty
needs to know which navigation property is currently being set in parent to find the correct matching property in child.
BTW is this project still maintained? This bug is really bad so I took the time to open an issue but I wasn't sure if this project was abandonned years ago or if someone picked it up again? Thanks!