How to save two entities together using a reposito

2019-09-11 05:56发布

问题:

This is my IGenericRepository

public interface IGenericRepository<T>
{
    IEnumerable<T> GetAll();
    IEnumerable<T> GetMany(Func<T, bool> predicate);
    void Insert(T obj);
    void Save();

}

and here is its implementation

public class GenericRepository<T> : IGenericRepository<T> where T : class
{
    private ApplicationDbContext db;
    private DbSet<T> table = null;

    public GenericRepository(ApplicationDbContext db)
    {
        this.db = db;
        table = db.Set<T>();
    }

    public IEnumerable<T> GetAll()
    {                           
        return table.ToList();
    }

    public IEnumerable<T> GetMany(Func<T, bool> predicate)
    {
        var data=table.Where(predicate);
        return data;
    }

    public void Insert(T obj)
    {
        table.Add(obj);
    }


    public void Save()
    {
        db.SaveChanges();
    }
}

Here is the repository class for Department

public interface IDepartmentRepository : IGenericRepository<Department>
{
    IEnumerable<Department> GetAlldepartment();


    void Save1();
}

public class DepartmentRepository : GenericRepository<Department>, IDepartmentRepository
{
    private ApplicationDbContext db;

    public DepartmentRepository(ApplicationDbContext db):base(db)
    {
        this.db = db;
    }

    public IEnumerable<Department> GetAlldepartment()
    {
       var v= from c in db.Departments
                select c;

        return v;
    }



    public void Save1()
    {
        db.SaveChanges();
    }

}

As same I have another repository for Customer

public interface ICustomerRepository : IGenericRepository<Customer>
{
    IEnumerable<Customer> SelectAll();
    void Update(Customer obj);
    void Delete(string id);


}

public class CustomerRepository : GenericRepository<Customer>, ICustomerRepository
{
    private ApplicationDbContext db;

    //public CustomerRepository()
    //{
    //    this.db = new ApplicationDbContext();
    //}

    public CustomerRepository(ApplicationDbContext db)
        : base(db)
    {
        this.db = db;
    }

    public IEnumerable<Customer> SelectAll()
    {
        var data = this.GetMany(a => a.Id == 1);

        return data;
    }      

    public void Update(Customer obj)
    {
        db.Entry(obj).State = EntityState.Modified;
    }

    public void Delete(string id)
    {
        Customer existing = db.Customers.Find(id);
        db.Customers.Remove(existing);
    }

}

and finally my controller is

public class DepartmentController : Controller
{
    DepartmentRepository _departmentRepository=null;
    ICustomerRepository _customerRepository=null;
    ApplicationDbContext _context = new ApplicationDbContext();
    public DepartmentController()
    {
        this._departmentRepository = new DepartmentRepository(_context);
        this._customerRepository = new CustomerRepository(_context);
    }


    public ActionResult Index()
    {
        var data = _departmentRepository.GetAlldepartment();
        return View(data);
    }
    public ActionResult Create()
    {
        return View();
    }
    [HttpPost]
    public ActionResult Create(Department Department)
    {
        _departmentRepository.Insert(Department);

        List<Customer> list = new List<Customer>();
        for (int i = 0; i < 5; i++)
        {
            list.Add(new Customer
            {
                Id = i,
                Name = i + " Hi"

            });
            _customerRepository.Insert(list[i]);
        }
        _departmentRepository.Save();
        return RedirectToAction("Index");
    }
    protected override void Dispose(bool disposing)
    {

        base.Dispose(disposing);
    }
}

If I want to save Department and Customer from DepartmentController, then I just create an instance of my DBcontext object and pass same object to both repository classes. Is there any problem? If so please help me how I can do this.

回答1:

Create a TransactionScope in an ActionFilter and put it on your controller action

[AttributeUsage(AttributeTargets.Method)]
public class TransactionScopeAttribute : ActionFilterAttribute
{
    private TransactionScope TransactionScope { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        TransactionScope =
            new TransactionScope(TransactionScopeOption.Required, new TransactionOptions
            {
                IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted
            });
    }
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (TransactionScope == null)
            return;

        if (filterContext.Exception == null)
        {
            TransactionScope.Complete();
            return;
        }

        TransactionScope.Dispose();
    }
}