Can entities be deleted without the ObjectContext? - c#

Using the default code generated entities with Entity Framework, is there a way to delete an entity object without using the ObjectContext? For example, self-tracking entities have a MarkAsDeleted method. Also, the ObjectContext isn't needed to update or add objects, so I'm hoping the same applies to deleting objects.
One thing that doesn't work is to simply mark the entity as deleted since the property is readonly:
foo.EntityState = EntityState.Deleted;

Answer seems to be no, so I'm using a technique I wrote about before to attach the ObjectContext to all entities that need to delete child entities: http://sixfeetsix.blogspot.com/2012/06/provide-entityobjects-access-to-their.html

Related

How does Entity Framework Core know and identify which record to update?

Hopefully a quick one, I'm new to C# / .NET Core / Entity Framework etc. but need to use it for work so apologies if this makes no sense.
I'm going to update a record using Entity Framework Core update method, but I'm not sure how it identifies which record to update? Does it compare the record's ID?
My plan is to replace the original entity with a new entity with new values every time - but the ID will remain the same, is this sufficient or do I need to map the new properties to the existing entity?
Thanks
Check that source here: https://learn.microsoft.com/en-us/ef/core/change-tracking/identity-resolution
Everything for ef core tracking.
Entity instances become tracked when they are:
Returned from a query executed against the database
Explicitly attached to the DbContext by Add, Attach, Update, or similar methods
Detected as new entities connected to existing tracked entities
Entity instances are no longer tracked when:
The DbContext is disposed
The change tracker is cleared (EF Core 5.0 and later)
The entities are explicitly detached

Add entity relationship to EF Core scaffolded entity when database cannot be changed - and retaining the addition on rescaffold

I am using a database-first approach to a third party database that I cannot change. The database has two tables that should have a constraint defining their primary/foreign key relationship. The constraint is missing so the entities generated do not have the relationship. Is it possible to add the entity relationships to the scaffolded entities without losing my additions if I need to scaffold again (due to an upgrade etc)?
I've thought about creating a custom partial class file extending the existing entity but this will not work if the existing entity already has a constructor. I need a constructor to instantiate a HashSet<T> of the other side of the relationship. I've also thought about using inheritance but not sure if that will work well with the existing entity.
Update: It seems like easiest solution may be to instead use linq join syntax and not provide the relationship in the entities but I'll leave the question up in case anyone has a good solution and a use case where it is beneficial.

Entities fetched as ReadOnly in NHibernate are present in PersistenceContext

I'm working on a project which uses NHibernate as an ORM.
A fairly large number of entities can be loaded into the session as 'readonly' since they should not be updated after retrieval.
I've tried to do this in 2 different ways:
var entity = criteria.UniqueResult<MyType>();
_session.SetReadOnly(entity, true);
or:
criteria.SetReadOnly(true);
In both ways however, I can see that the entity is present in the PersistenceContext of the ISession.
Is this normal ? I'd expect that, since the entity is readonly/immutable, it should not be present in the PersistenceContext.
The entity type is a complex type; it has multiple associations to other types.
There are some limitations to the Read-Only functionality in nhibernate. The name of the function lets one expect a harder warranty of preventing object changes.
If you look at the documentation (http://nhibernate.info/doc/nh/en/index.html#readonly) there are many exceptions that could lead to unintended changes in the database.
From the docs:
When an entity is read-only:
NHibernate does not dirty-check the entity's simple properties or
single-ended associations
NHibernate will not update simple properties or updatable
single-ended associations
NHibernate will not update the version of the read-only entity if
only simple properties or single-ended updatable associations are
changed
In some ways, NHibernate treats read-only entities the same as entities that are not read-only:
NHibernate cascades operations to associations as defined in the
entity mapping.
NHibernate updates the version if the entity has a collection with
changes that dirties the entity;
A read-only entity can be deleted.
Considering your expectations it think Objects are always added to the Persistence-Context even if they are load Read-Only. Otherwise the Identity-Map -Pattern would not hold. In the Persistence-Context there is a Flag that signals that an entity is Read-Only.
In the context the state can be checked by opening the individual entity entry.

How to maintain data after DbSet.Remove?

I use a repository pattern and to make things centralized I created a IValidate interface that each of my repositories can implement. In that I make entity validations depending on their state. So far so good, until I removed an entity. When I tried to access a property from a removed entity I got an exception, the entity was no longer in context.
Ex:
class A
{
int MyClassBId
B MyClassB
}
If I add or update entity A I can access A.MyClassB with no hassle. But if I delete (DbSet.Remove) even before calling SaveChanges (my approach of course calls this Validations before save) the references are null. So if I try to access A.MyClassB again I get null reference, but the "not lazy-loaded" objects are there. For instance, A.MyClassBId still has the FK for B.
I understood that DbSet.Remove only marked the entity for deletion, nothing else. Does it also remove it from context? How can I solve this? Call DbSet.Remove and still maintain the references in the object, at least until SaveChanges is called?
Thanks.
You have to understand that two processes are going on:
Entity Framework keeps track of the entities that are loaded in DbContext, maintaining their state as Added, Modified, Deleted or Unchanged. You can check this with a MyDataContext.Entry(MyEntity).Statecall.
Outwardly the POCO classes behave just like you would expect from classes that have no connection to an ORM whatsoever.
So what happens when you call the DbSet.Remove method is that the entity will be marked for deletion under the covers and outwardly it will be removed from the ICollection that it belonged too.
If you want to keep track of entities that should be deleted on a SaveChanges call you will have to define a WillBeDeleted property on the entity and your code will have to take this property into account when counting active entities, validation, etc. The actual DbSet.Remove call should then be made just before calling SaveChanges.
Alternatively, you can use MyDataContext.Configuration.AutoDetectChangesEnabled=False before initialising the DbContext. Now the Entity that is subjected to the DbSet.Remove method will not be deleted from its ICollection in the POCO class, but you have no way of knowing that the entity is meant to be deleted without again tracking this in a property of your own.

Generic method for comparing 2 objects and update changes from one to the other in c#

Problem case:
My problem is editing disconnected POCO entities and then saving them to the database (Uisng Entity Framework). When doing so, the generated sql updates ALL properties even though only some have actually changed. When I do the same within the context, the generated sql correctly updates only the modified properties. This causes problem with my auditing code since it wrongly stores changes on all the properties. This is made worst when the entity I am persisting has a complicated model with many relationships.
My proposed solution:
Instead of attaching the modified entity to the context, I want to query the entity and then manually syncronize the two object with a generic method that will work for any model. So I need to compare all properties from each object and update the modified properties to the attached entity. How do I go about updating the values in the properties, keeping in mind that changes might include new or modified relationships ?
Any thoughts?

Categories