Skip to content

Data corruption when fixing up navigation properties #185

@jods4

Description

@jods4

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!

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions