1

I have a MVC Action that imports data from a CSV file using EF. When I read a new record from CSV, I need to check if that record already exists including records that I have already imported before Saving, so I can update it instead of creating a new record.

The simple solution is to just SaveChanges() after every dbContext.Entities.Add(newEntity) call but I suspect that is not very efficient. It also means that I cannot rollback (easily) to prior to beginning the import. I.e. if any part of the import fails, I can avoid calling SaveChanges()

My question is: Can I search "Added" entities, then update them, before I call dbContext.SaveChanges() once, at the end of my import routine?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
tr3v
  • 431
  • 1
  • 9
  • 19
  • There is some more info needed: how many rows are you adding? How many rows are still in the database table? How do you match a row in the CSV with a row in the DB? This can help determine which will be the fastest way to do it. – JotaBe Dec 02 '13 at 09:05
  • @JotaBe there are 1000's of records in the database table and only importing at most 200 each time. I am wanting to match the imported data by a couple of non-key fields. – tr3v Dec 02 '13 at 16:44

2 Answers2

0

Yes, you can check if each imported entity already exists in the database. Use the same context, and try to find them, one by one, in the database.

If the entity doesn't exists in the database leave it as is (tha is, in the Added state)

If the entity already exists in the database, modify the entity loaded from the DB: it was unchanged, because you had just read it from the DB, but, when you modify it, it will be in the Modified status, so that, when you save changes, it will be updated. But there is still a very important step: the imported entity which you have found in the database must be detached from the context so that it's ignored when you call SaveChanges().

If you don't understand what is to detach an entity, please, read this intereeting article: Entity Framework Add Remove Attach and Detach.

This solve your problem for saving all changes in one single operation.

JotaBe
  • 38,030
  • 8
  • 98
  • 117
  • Thanks @JotaBe, but this is not what I am after. I need to check the list of entities that have been Added (as I go) but not yet committed to the database. Querying the database returns a null entity even though I have already added it. – tr3v Dec 02 '13 at 18:16
0

You can search the "local" dataset before it is committed (i.e. before a call to SaveChanges() is made). Please note that I am using EF5.

As an example, the following search of the database returns null.

Entity myEntity = new Entity() { Name = "search text" };
db.Entities.Add(myEntity);
existingEntity = db.Entities.(e => e.Name == myEntity.Name).SingleOrDefault();

But the following subsequent call will find the Added entity before changes are saved allowing me to make further changes.

existingEntity = db.Set<Entity>().Local
    .Entities.(e => e.Name == myEntity.Name).SingleOrDefault();
tr3v
  • 431
  • 1
  • 9
  • 19
  • If you don't explain more clearly the whole process, it will be very hard to help you. Show more code, and explain what you want to achieve and why you cannot do it. I'm sorry, but I can't understand what you're doing. I don't mind if it's EF 4, 5 or 6... I¡m sure there are solutions in all of them, but only if I understand the problem. – JotaBe Dec 03 '13 at 00:43
  • @JotaBe I appreciate you trying to help, but I have found the answer out for myself - the solution is above. I think it may only be valid for EF5+ though. The key part of the solution is "db.Set().Local" which provides access to entities that have not yet been saved. I am not sure how I could have explained myself any clearer. – tr3v Dec 03 '13 at 01:24