Base solution for your next web application
Open Closed

SaveChanges not saving data to db immediately #1797


User avatar
0
mmax created

Hi. I need to insert and immediately save changes to db, but for some reason there is no data in the db after saving changes. Its inserting the data only after controller was totally executed.

This is simplified example of my code:

public class Car : Entity
    {
        public string Name { get; set; }
    }
public interface ICarRepository : IRepository<Car>
    {
        Task SaveChangesAsync();
    }

    public class CarRepository : BaseRepository<Car>, ICarRepository
    {
        public CarRepository(IDbContextProvider<PropertyIntelDbContext> dbContextProvider) : base(dbContextProvider)
        {
        }

        public async Task SaveChangesAsync()
        {
            await Context.SaveChangesAsync();
        }
    }
public async Task<ActionResult> InsertCar()
        {
            await _carRepository.InsertAsync(new Car
            {
                Name = "test"
            });

            await _carRepository.SaveChangesAsync();

            return Content("Ok");
        }

Should be something simple. What am I doing wrong? How to force insert the data?


4 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    You don't need to create custom repository for that. See <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#DocUowSaveChanges">http://www.aspnetboilerplate.com/Pages/ ... aveChanges</a>

  • User Avatar
    0
    mmax created

    <cite>hikalkan: </cite> You don't need to create custom repository for that. See <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#DocUowSaveChanges">http://www.aspnetboilerplate.com/Pages/ ... aveChanges</a>

    In my case I need custom repository. Also this repository is called from service, not from the controller. I'm trying to show you only root of the problem.

    In other words I need to make a commit of transaction just after SaveChanges, not disposing the DbContext. Is that possible?

  • User Avatar
    0
    gpcaretti created

    In EF, database commits are normally visible only at the end of the transaction or once you call the commit() method or scope.complete() method.

    If you take a look to the Abp Unit of Works source code you see:

    protected override void CompleteUow()
            {
                SaveChanges();
                if (CurrentTransaction != null)
                {
                    CurrentTransaction.Complete();
                }
                DisposeUow();
            }
    
            protected override async Task CompleteUowAsync()
            {
                await SaveChangesAsync();
                if (CurrentTransaction != null)
                {
                    CurrentTransaction.Complete();
                }
                DisposeUow();
            }
    

    It follows the same approach of teh EF.

    So, to close, these are the main reasons you don't see your changes in the DB.

    I suggest you two approaches:

    1. Play with the DB isolationLevel so that you can read dirty data.
    2. More clean: Use the Abp events. Register a method to the Committed event , Call SaveChangesAsync, that exit from your event. In this way the Commit Event will be fired for your post-commit operations.

    Further info here: <a class="postlink" href="https://msdn.microsoft.com/en-us/data/dn456843.aspx">https://msdn.microsoft.com/en-us/data/dn456843.aspx</a>

  • User Avatar
    0
    mmax created

    <cite>gpcaretti: </cite>

    1. Play with the DB isolationLevel so that you can read dirty data.
    2. More clean: Use the Abp events. Register a method to the Committed event , Call SaveChangesAsync, that exit from your event. In this way the Commit Event will be fired for your post-commit operations.

    Thanks a lot! I will try.