Optimus
Optimus

Reputation: 2210

Entity framework 6 transaction

I need to insert new rows in two of my tables first table's auto generated id field is one of the field of second table .currently I'm using transaction for inserting data. My current code is given below

        using (var context = new ApplicationDatabaseEntities())
        {
            using (var transaction = context.Database.BeginTransaction())
            {
                try
                {
                   foreach (var item in itemList)
                   {
                    context.MyFirstEntity.Add(item);
                    context.SaveChanges();

                    mySecondEntity.MyFirstEntityId = item.Id;
                    context.MySecondEntity.Add(mySecondEntity.MyFirstEntityId );
                    context.SaveChanges();

                   }
                  transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    Console.WriteLine(ex);

                }
            }
        }

The above code is working fine .my question is, is this the correct way? I mean if I have 1000 or 2000 items for insertion does my current code affect the performance

Upvotes: 2

Views: 762

Answers (3)

Loetn
Loetn

Reputation: 4040

You should wrap your transaction in a using statement and rollback when an exception is thrown.

using (DbContextTransaction transaction = context.Database.BeginTransaction())
{
   try
   {
      foreach (var item in itemList)
      {
         context.MyFirstEntity.Add(item);
         mySecondEntity.MyFirstEntity = item;
         context.MySecondEntity.Add(mySecondEntity);
      }

      transaction.Commit();
   }
   catch (Exception e)
   {
      transaction.Rollback();
   } 
}

More info here.

Upvotes: 1

Giorgi Nakeuri
Giorgi Nakeuri

Reputation: 35780

It depends. If the whole batch has to be transactional then you have no other way as do in one big transaction. If transaction has to be guaranteed for tupples only then if the time of transaction is big enough you may face some locks. Then you can just do transaction in the loop for each tupple.

Also you can do what you are doing in one go without explicit transaction. You can SaveChanges after the loop and it will be transactional:

foreach (var item in itemList)
{
    context.MyFirstEntity.Add(item);
    mySecondEntity.MyFirstEntity = item;
    context.MySecondEntity.Add(mySecondEntity);
}
context.SaveChanges();

Upvotes: 1

Alexander Polyankin
Alexander Polyankin

Reputation: 1887

Code can be improved with implicit transaction:

foreach (var item in itemList)
{
    context.MyFirstEntity.Add(item);
    mySecondEntity.MyFirstEntity = item;
    context.MySecondEntity.Add(mySecondEntity);
}
context.SaveChanges();

Note: instead of id I've used navigation property.

Upvotes: 4

Related Questions