0

I’m working on a system which revolves around objects called Units. The structure between these Units are constantly changing and I must keep track which predecessors and successors these objects have.

So I have made a self-referencing many-to-many relationship according to this post

For context, my code:

The Unit Entity:

    {
        public int UnitId { get; set; }
        ...
        public IList<HistoricalUnitRelation> Predecessors { get; set; }
        public IList<HistoricalUnitRelation> Successors { get; set; }

    }

The class representing the join table:

    {
        public int PrecedingUnitId { get; set; }
        public Unit PrecedingUnit { get; set; }
        public int SucceedingUnitId { get; set; }
        public Unit SucceedingUnit { get; set; }
    }

And the Fluent API config:

            builder.Entity<HistoricalUnitRelation>()
                .HasKey(hisur => new { hisur.PrecedingUnitId, hisur.SucceedingUnitId });

            builder.Entity<HistoricalUnitRelation>()
                .HasOne<Unit>(hisur => hisur.PrecedingUnit)
                .WithMany(u => u.Predecessors)
                .HasForeignKey(hisur => hisur.PrecedingUnitId)
                .OnDelete(DeleteBehavior.Restrict); 

            builder.Entity<HistoricalUnitRelation>()
                .HasOne<Unit>(hisur => hisur.SucceedingUnit)
                .WithMany(u => u.Successors)
                .HasForeignKey(hisur => hisur.SucceedingUnitId)
                .OnDelete(DeleteBehavior.Restrict);

I should also mention that I'm using a PostgreSQL (12.2) Database with The Postgis (2.5.4) extention. (and the npgsql EF Core provider of course)

This is all migrated without any problems but I'm getting some real weird behavior when trying to save objects using this relation.

Code I'm using to save the Unit objects:

if (unitDTO.PredecessorIds != null)
            {
                List<HistoricalUnitRelation> predecessors = new List<HistoricalUnitRelation>();
                List<Unit> predecessorUnitObjects = _context.Units.Where(u => unitDTO.PredecessorIds.Contains(u.UnitId)).ToList();
                foreach (Unit predecessorUnitObject in predecessorUnitObjects)
                {
                    HistoricalUnitRelation historicalUnitRelation = new HistoricalUnitRelation() { PrecedingUnit = predecessorUnitObject , SucceedingUnit = unit };
                    predecessors.Add(historicalUnitRelation);

                }
                unit.Predecessors = predecessors;
            }

The code above should find the desired units and add them to the new Unit's predecessor list.

Everything seems to be working as intended until it's time to save the new object:

imgur link to object pre-save

Pre saving the object everything looks as it should be, unit with ID 36 should be the predecessor and the newly created object should be the successor.

imgur link to object post-save

After saving the object something weird happens; the newly created unit with ID 40 has become both the predecessor AND the successor. Something somewhere must've gone wrong but I can't seem to pinpoint what exactly causes this behavior. The most curious thing of all is that I already have defined multiple many-to-many relationships, albeit between different objects, and those seem to work perfectly.

  • 1
    Summarize “weird behavior” and rewrite the title with such. – user2864740 May 17 '20 at 18:37
  • @user2864740 i've changed the title to be more specific – Ömer Sayilir May 17 '20 at 18:41
  • Try `unit.Predecessors.Add(historicalUnitRelation)`. And please don't post images of code and/or values. Always use text unless *absolutely* impossible. – Gert Arnold May 17 '20 at 20:04
  • @GertArnold thank you for the tip but sadly that didn't seem to be the cause. Regarding the second part of your answer, thanks for the feedback, I will remember it when posting questions in the future! – Ömer Sayilir May 17 '20 at 20:16

0 Answers0