Reputation: 1383
Idea: I have a Key entity, which can be replaced (rotated) by other Key with a delay. I was thinking of implementing it as:
class Key {
string Id;
string ReplacesId;
Key Replaces;
string ReplacedById;
Key ReplacedBy;
DateTime Expires;
// ...
}
So when I want to replace it, I'd create another key and then reference new and old keys to each other. And if anyone of them is deleted, the other one would be as well.
And that's how I implemented, with this Fluent mapping:
modelBuilder.Entity<Key>().HasOne(x => x.ReplacedBy)
.WithOne(x => x.Replaces)
.IsRequired(false)
.OnDelete(DeleteBehavior.Cascade);
Replacement logic:
oldKey.ReplacedBy = newKey;
oldKey.ReplacedById = newKey.Id;
newKey.Replaces = oldKey;
newKey.ReplacesId = oldKey.Id;
_dbContext.Keys.Update(newKey);
_dbContext.Keys.Update(oldKey);
await _dbContext.SaveChangesAsync();
But it seems that ReplacedById
ReplacesId
or one of them are used like regular fields ant not FK, because when I try to delete one of them, they don't cascade.
Could I make this work, or should I just introduce Rotations/Replacements
table?
Upvotes: 4
Views: 434
Reputation: 32059
But it seems that ReplacedById ReplacesId or one of them are used like regular fields ant not FK, because when I try to delete one of them, they don't cascade.
This is because your Fluent API
configuration is not done in correct way. It actually should be as follows:
modelBuilder.Entity<Key>().HasOne(k => k.Replaces)
.WithOne()
.HasForeignKey<Key>(k => k.ReplacesId)
.IsRequired(false);
modelBuilder.Entity<Key>().HasOne(k => k.ReplacedBy)
.WithOne()
.HasForeignKey<Key>(k => k.ReplacedById)
.IsRequired(false);
Now everything will generate and work as expected!
Note: It will generate onDelete: ReferentialAction.Restrict
because you cannot cascade between them because it will cause multiple cascade paths.
Upvotes: 2