Giải pháp tốt nhất là sử dụng Đơn vị công việc để bọc bối cảnh dữ liệu, cũng như quản lý thời gian kết nối và cho phép bạn làm việc với nhiều kho lưu trữ (nếu bạn có xu hướng đi xuống đường dẫn đó) .
Tóm tắt thực hiện:
- Tạo một giao diện (
IUnitOfWork
) mà thấy nhiều thuộc tính cho DbSet
của bạn 's, cũng như một phương pháp duy nhất gọi là Commit
- Tạo một thực hiện (
EntityFrameworkUnitOfWork
), thực hiện theo yêu cầu. Cam kết chỉ cần gọi số SaveChanges trên lớp cơ sở (DbContext
) và cũng cung cấp một móc nối tốt cho logic phút cuối cùng.
- điều khiển của bạn chấp nhận một
IUnitOfWork
, sử dụng DI (tốt nhất) để giải quyết một EntityFrameworkUnitOfWork
, với một HTTP bối cảnh scoped đời thiết lập (StructureMap là tốt cho việc này)
- (không bắt buộc, nhưng khuyến khích) tạo ra một Repository cũng mất
IUnitOfWork
và làm việc đó thông qua Bộ điều khiển của bạn.
HTH
EDIT - Trong Response to Comments
Oh, làm thế nào bạn có thể làm công việc có liên quan đến việc tạo ra các bản ghi trong nhiều mô hình sau đó? tức là, tạo người dùng mới và bài đăng mới trong cùng một giao dịch.
Với việc sử dụng ASP.NET MVC, bộ điều khiển của bạn nên chấp nhận một IUnitOfWork
trong hàm tạo của chúng.
Dưới đây là một ví dụ, dựa trên những gì bạn hỏi
public SomeController : Controller
{
private IUnitOfWork _unitOfWork;
private IUserRepo _userRepo;
private IPostRepo _postRepo;
public SomeController(IUnitOfWork unitOfWork, IUserRepo userRepo, IPostRepo postRepo)
{
_unitOfWork = unitOfWork; // use DI to resolve EntityFrameworkUnitOfWork
_userRepo = userRepo;
_postRepo = postRepo;
}
[HttpPost]
public ActionResult CreateUserAndPost(User user, Post post)
{
// at this stage, a HTTP request has come in, been resolved to be this Controller
// your DI container would then see this Controller needs a IUnitOfWork, as well
// as two Repositories. DI smarts will resolve each dependency.
// The end result is a single DataContext (wrapped by UoW) shared by all Repos.
try
{
userRepo.Add(user);
postRepo.Add(post);
// nothing has been sent to DB yet, only two objects in EF graph set to EntityState.Added
_unitOfWork.Commit(); // two INSERT's pushed to DB
}
catch (Exception exc)
{
ModelState.AddError("UhOh", exc.ToString());
}
}
}
Và thêm một câu hỏi, những gì hiện các HTTP bối cảnh scoped đời làm gì?
Đối tượng trong DI-talk có các cài đặt quản lý phạm vi bao gồm cho mỗi thread, mỗi phiên, theo yêu cầu http, singleton vv
HTTP bối cảnh scoped là cài đặt khuyến khích cho các ứng dụng web. Nó có nghĩa là "mới lên một bối cảnh khi một yêu cầu HTTP đi vào, và loại bỏ nó khi yêu cầu kết thúc".
Ngoài ra khi bạn sử dụng UnitOfWork với ORM, bạn cần lưu ý rằng nếu cam kết không thành công thì bạn cần một bối cảnh/đơn vị công việc mới http://lavinski.tumblr.com/post/9114111237/object-relational-mapper -exceptions –