Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the most reasonable way to find out if entity is attached to dbContext or not?

when i try to attach entity to context i get an exception

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key

This is expected behaviour.

But i would like to know how ObjectStateManager knows that? I would like to do this check by myself before

like image 473
maxlego Avatar asked May 17 '11 15:05

maxlego


People also ask

What happens if you don't dispose DbContext?

Although the DbContext implements IDisposable , you shouldn't manually dispose it, nor should you wrap it in a using statement. DbContext manages its own lifetime; when your data access request is completed, DbContext will automatically close the database connection for you.

Which method of DbContext is used to save entities to the database?

SaveChanges() This method will automatically call DetectChanges() to discover any changes to entity instances before saving to the underlying database. This can be disabled via AutoDetectChangesEnabled. Entity Framework Core does not support multiple parallel operations being run on the same DbContext instance.

Which method is used to add a DbContext to an application?

The OnConfiguring() method allows us to select and configure the data source to be used with a context using DbContextOptionsBuilder . Learn how to configure a DbContext class at here.

Should you use using with DbContext?

EF and EF Core DbContext types implement IDisposable . As such, best practice programming suggests that you should wrap them in a using() block (or new C# 8 using statement). Unfortunately, doing this, at least in web apps, is generally a bad idea.


2 Answers

If you are using DbContext API (you mentioned ef-code-first) you can simply use:

context.YourEntities.Local.Any(e => e.Id == id); 

or more complex

context.ChangeTracker.Entries<YourEntity>().Any(e => e.Entity.Id == id); 

In case of ObjectContext API you can use:

context.ObjectStateManager.GetObjectStateEntries(~EntityState.Detached)                           .Where(e => !e.IsRelationship)                           .Select(e => e.Entity)                           .OfType<YourEntity>()                           .Any(x => x.Id == id); 
like image 131
Ladislav Mrnka Avatar answered Oct 08 '22 04:10

Ladislav Mrnka


Here's an extension method for getting the object from the context without having to worry about whether it is already attached:

public static T GetLocalOrAttach<T>(this DbSet<T> collection, Func<T, bool> searchLocalQuery, Func<T> getAttachItem) where T : class {     T localEntity = collection.Local.FirstOrDefault(searchLocalQuery);      if (localEntity == null)     {         localEntity = getAttachItem();         collection.Attach(localEntity);     }      return localEntity; } 

Just call:

UserProfile user = dbContext.UserProfiles.GetLocalOrAttach<UserProfile>(u => u.UserId == userId, () => new UserProfile { UserId = userId }); 
like image 23
David Sherret Avatar answered Oct 08 '22 04:10

David Sherret