Reputation: 1352
I have an Entity. Mandate
. Every mandate has a required:many relation to a Person (NavigationProperty). I use the DbContext API with (LazyLoadingEnabled, AutoDetectChangesEnabled, ValidateOnSaveEnabled, ProxyCreationEnabled)
Now I like to delete a Mandate entity. The mandate entities are loaded by another context with AsNoTracking()
.
message.Result.
ObserveOn(On<DataComposition>.Scheduler).
Where(r => r).
Subscribe(_ =>
{
using (var unit = UnitOfWork.Begin())
{
var mandate = this.SelectedItem.OriginalEntity;
this.mandateRepository.Attach(mandate);
// mandate.Person.ToString();
this.mandateRepository.Delete(mandate);
unit.Commit();
}
this.List.RemoveOnUi(this.SelectedItem);
});
Now during committing I get the following exception: Entities in 'CodeFirstContainer.Mandates' participate in the 'Mandate_Person' relationship. 0 related 'Mandate_Person_Target' were found. 1 'Mandate_Person_Target' is expected.
The delete works if I include the Person Property during the population/selection or if I visit the Property (lazyloading), but I DONT LIKE to materialize/hold many entities only for the deletion case and I DONT LIKE to trigger more than a single DELETE
query to db!
Upvotes: 2
Views: 440
Reputation: 177163
The fact that, if you have the navigation property mandate.Person
populated, the following SQL statement ...
delete [dbo].[Mandates]
where (([Id] = @0) and ([PersonId] = @1))
... is sent to the database, lets me think that the navigation property indeed must be populated with a person with the correct PersonId
to delete the parent.
I have no idea why Entity Framework just doesn't send a delete statement with the primary key ...
delete [dbo].[Mandates]
where ([Id] = @0)
... as I had expected.
Edit
If the Mandate
entity has a foreign key property PersonId
for the Person
navigation property, the expected SQL (the second above) is sent to the database. In this case the Person
navigation property can be null
and the value of the FK property PersonId
doesn't matter.
Edit 2
If you don't want to introduce a FK property the way with the least DB-roundtrip-costs would probably be to fetch the person's Id and then create a dummy person with that key in memory:
// ...
var personId = context.Mandates
.Where(m => m.Id == mandate.Id)
.Select(m => m.Person.Id)
.Single();
mandate.Person = new Person { Id = personId };
this.mandateRepository.Attach(mandate);
this.mandateRepository.Delete(mandate);
// ...
Upvotes: 2