1

I'm trying to do a couple of related insertions in a transaction and for some reason EF keeps inserting multiple duplicate records. The closest I could find here is the many-to-many issue, but that doesn't solve my problem.

Here's what I'm trying to do:

public void UploadFilesToStorage(MetadataLineCollection metadata, string outputDirectory)
    {
        using (var scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromMinutes(15)))
        using (var context = new DbEntities())
        {
            decimal newJobId = CreateNewJob(context, metadata.CommonMetadata.OriginalFileName);

            foreach (var item in metadata.Items)
            {
                var fingerprint= service.UploadFile(outputDirectory + "\\" + item.TifFileName);
                StoreFileInfo(context, newJobId, imageFingerprint, item);
            }

            var csvFingerprint = service.UploadFile(outputDirectory + "\\" + metadata.CsvFileName);
            StoreFingerprint(context, newJobId, csvFingerprint);
            CreateNewDelivery(context, newJobId);

            scope.Complete();
            context.AcceptAllChanges();
        }
    }

As you can see, I'm passing the same context to each function that's supposed to use related data. Each of those calls context.SaveChanges(false).

Still, multiple identical jobs are being created (but only the first one has the fingerprint, since the rest has different jobIds), and each metadata item is stored multiple times, too! Also, the amount of duplicates is different (for one metadata item it's 8, for another it's 3, etc...)

Am I missing something here?

Ch1mp
  • 45
  • 1
  • 8

1 Answers1

2

According to the MSDN Documentation for the acceptChangesDuringSave parameter of ObjectContext.SaveChanges

If true, the change tracking on all objects is reset after SaveChanges(Boolean) finishes. If false, you must call the AcceptAllChanges method after SaveChanges(Boolean)

This should mean that all objects in the change tracker will still have the state of Modified or Added, and subsequent calls to SaveChanges() will persist them again.

Try either removing the false parameter, or don't call SaveChanges() at all inside your various methods and call it once later on

Chris Curtis
  • 1,478
  • 1
  • 10
  • 21
  • I didn't know there were was such a dependency, thanks! Although that brings about a different problem in that, due to not actually hitting the database, I'm not getting a jobId from the first call - it's always equal to zero. So I have to persist at least that change, since the rest is dependent on it. Maybe I'll just try saving that and removing it in catch block if something goes wrong? – Ch1mp Feb 18 '15 at 21:41
  • Turns out that I could just put independent contexts in each of the functions and whilst they were in the TransactionScope all worked well! Your hint gave food for thought, hence I'm marking it as the answer. Thanks again Chris. – Ch1mp Feb 18 '15 at 23:35