1

I will try to explain what I want, but it will be hard. ) So I have entity:

public class User
{
    [Key]
    public Int32 Id { get; set; }
    public String Name { get; set; }
    public List<Article> Article { get; set; }

    public String Surname { get; set; }
}

I have the realization of DbContext and its interface:

public interface IMyContext
{
    DbSet<T> Set<T>() where T : class;
}

public class MyContext : DbContext, IMyContext
{
    public DbSet<User> Users { get; set; }

    protected override void Dispose(bool disposing)
    {
        this.SaveChanges();
        base.Dispose(disposing);
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //modelBuilder.Entity<User>().HasMany(e => e.Article).WithRequired(e => e.User).WillCascadeOnDelete(true);
        base.OnModelCreating(modelBuilder);
    }
}

I have the this entity repository and it's interface:

public interface IUserRepository
{
    void Add(User entity);
    void Delete(User entity);
    User GetById(Int32 id);
    List<User> GetAll();
}

public class UserRepository : RepositoryBase<User>, IUserRepository
{
    [Inject]
    public UserRepository(IMyContext context):base(context)
    {
    }
}

Also I'm using ninject to inject dependency. In the usage it looks like this(dont tell me that I shouldn't use the repository in my pressentation layer directly, I should use it through the BussinesLogic layer. It's just an example):

    var repository = DI.Resolve<IUserRepository>();
    repository.Add(new User(){Name="Vasja1", Id = 1, Surname = "Petrov"});

Let's imagine that we have in our pressentation layer the Asp.NET application. There is a lot of places where my application can modify entities. Question where i should use SaveChanges()? I put it in context.Dispose() method but dispose also have to be called. Thx for answers. Will be very gratitude if you will show the example.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Maris
  • 4,608
  • 6
  • 39
  • 68

2 Answers2

1

If you follow the MVC pattern you could wrap the repository call inside a using statement in a controller' action. The last line in the using block could be the .SaveChanges(). You can also search for a transaction / unit of work pattern.

Raxr
  • 965
  • 7
  • 12
1

I dont think savechanges in dispose is a good idea.

You can implement a SaveChnages on you repository Class, but you will often see a Logical Unit of Work pattern used. Here is a brief explanation of such a pattern.

public interface ILuw
   OperationStatus Commit();


  public class UoW : IUow
{

  // Constructor... inject context....

     // Properties/Members that work with your repository Interface pattern

      public DbSet<Users> Users  // example
      public DbSet<Entity2>

   public OperationStatus Commit()
    {
     Context.SaveChanges();
     }


}

So now you can even Inject the Unit of Work class/Interface. It is in turn containing Repositories which follow an Interface pattern.

The Luw in instantiated with a context. You will do via Injection but for demo sake

 var myLuw = new Luw(MyContext);
 myLuw.RepositoryPatternofEntityT.Get  // or add, remove etc.
 // otehr rpository changes

 myLuw.Commit

The Luw class could implement Idisposable. But Dont put the Save in dispose. Call commitwhen the change set should be commited.

You may then dispose of the Luw or use it again... another discussion

phil soady
  • 11,043
  • 5
  • 50
  • 95
  • But how it will help me with calling `SaveChanges()` only once pre run? in one .ascx file I call Commit it's instantly fly in to the DB, second .ascx file loaded there is also a Commit, these will make the second query to the DB – Maris Feb 18 '13 at 11:08
  • Issue the commit when required. If you feel the only pattern that works for you is dispose and that is well managed. You can do it there. I say dont put it there since you regularly see posts with people having issues placing "save" logic inside a garbage collection process. I personally dont like that pattern. But if you know that process well do it. Treat my comment as a general recommendation. Not something that cant work. I take the view. Something triggers the "end" of a unit of work. Call commit then start any garbage collection required. – phil soady Feb 18 '13 at 11:18
  • an example from yesterday. and Im not the only one recommending save in garbage collection processing isnt ideal. http://stackoverflow.com/questions/14919543/dbcontext-has-been-disposed-and-autofac – phil soady Feb 18 '13 at 11:20
  • Can you send me pls the good example of UnitOfWork in use? I will be very gratitude. – Maris Feb 18 '13 at 11:30
  • sorry cant send our code, can suggest basic templates like http://codereview.stackexchange.com/questions/276/interface-for-unit-of-work-pattern-and-repository-pattern and this SO post http://stackoverflow.com/questions/995227/can-anyone-recommend-good-tutorial-on-repository-and-unit-of-work-pattern-usage – phil soady Feb 18 '13 at 11:37
  • "I dont think savechanges in dispose is a good idea.". I can confirm that. It's a terrible idea. This means everything will still get committed, even when the application throws an exception. You'll have a database full of incorrect state in no time. – Steven Feb 18 '13 at 13:07