2010-09-15 25 views
5

Tôi đang nghĩ về việc bắt đầu một dự án mới sử dụng EF 4 và trải qua một số điều làm việc, tôi thấy một bài viết về EF với mô hình kho và đơn vị công tác (http://blogs.msdn.com/b/adonet/archive/2009/06/16/using-repository-and-unit-of-work-patterns-with-entity-framework-4-0.aspx)thực thể đơn vị khung + kho + hoặc câu hỏi

Nhìn vào bài viết đó, nó sử dụng ObjectContext như UnitOfWork và nó chuyển nó tới Kho lưu trữ.

Câu hỏi của tôi là nếu tôi có 2 ObjectContext có nghĩa là tôi sẽ có 2 đơn vị công việc, nhưng tôi thực sự muốn tất cả các hoạt động thực hiện trên 2 ngữ cảnh đó là một đơn vị công việc. Tôi không muốn gọi lưu trên từng ngữ cảnh, tôi muốn nó được giao dịch .... mà không cần sử dụng transactioncope ...

Ví dụ, tôi có ngữ cảnh quản lý Nhật ký hoạt động và ngữ cảnh khác quản lý Đơn đặt hàng. Cho phép nói Trong lớp kinh doanh của tôi, tôi có một phương thức gọi là AddOrder(). AddOrder() sẽ sử dụng bối cảnh thứ tự để tạo một thứ tự mới, nhưng nó cũng sẽ sử dụng ngữ cảnh log hoạt động để tạo một mục nhật ký hoạt động mới. Vì đó là 2 bối cảnh, tôi sẽ phải gọi lưu trên cả hai bối cảnh để cam kết .... có lẽ tùy chọn duy nhất là chỉ có một bối cảnh duy nhất ....

EDIT: Tôi có nghĩa là 2 ngữ cảnh của các loại khác nhau ví dụ: OperationalLogContext và OrderContext.

Trả lời

12

Đúng - tôi tin rằng điều đó là có thể.

Trình kích hoạt là cách xử lý Kho lưu trữ của bạn.

Ví dụ, mỗi Kho lưu trữ nên có một bối cảnh .. do đó, chỉ cần tạo một ngữ cảnh và chuyển nó vào mỗi kho lưu trữ.

(đang xin vui lòng!) Vui mừng u hỏi :)

public interface IOrderRepository 
{ 
    IQueryable<Order> FindAll(); 
} 

public interface IOperationLogRepository 
{ 
    IQueryable<OperationLog> FindAll(); 
} 

public interface IUnitOfWork 
{ 
    void Commit(); 
} 

.

public class SqlServerContext : ObjectContext, IUnitOfWork 
{ 
    public void SqlServerContext(string connectionString) 
     : base(connectionString) 
    { 
    } 

    public void Commit() 
    { 
     this.SaveChanges(); 
    } 

    // Your other POCO's and stuff here ..etc.. 
} 

.

public class OrderRepostiory : IOrderRepository 
{ 
    private readonly SqlServerContext _sqlServerContext; 
    public void OrderRepostiory(SqlServerContext sqlServerContext) 
    { 
     _sqlServerContext = sqlServerContext; 
    } 

    public IQueryable<Order> FindAll() 
    { 
     _sqlServerContext.Orders; 
    } 
} 

.. và cuối cùng, instantiation. Gây ra một tốt lân cậu bé/cô gái/cầu vồng, bạn sẽ được sử dụng Dependency Injection ..

public class SqlServerRegistry : Registry 
{ 
    public SqlServerRegistry(string connectionString) 
    { 
     For<SqlServerContext>() 
      .HybridHttpOrThreadLocalScoped() 
      .Use<SqlServerContext>() 
      .Ctor<string>("connectionString") 
       .Is(connectionString); 

     For<IOrderRepository>().Use<OrderRepository>(); 
     For<IOperationLogRepository>().Use<OperationLogRepository>(); 
    } 
} 

và vì SqlServerContext được định nghĩa là HttpOrThreadLocal, nó sẽ được instantied một lần và tái sử dụng trong nhiều Repositories.

Không biết hoặc hiểu DI/IoC?

thì đây cũng sẽ làm việc ....

private SqlServerContext _sqlServerContext; 
private IOrderRepository _orderRepository; 
private IOperationLogRepository _operationLogRepository; 

[TestInitialize] 
public void TestInitialise() 
{ 
    _sqlServerContext = new SqlServerContext(
      ConfigurationManager.AppSettings["connectionString"]); 
    _orderRepository = new OrderRepository(_sqlServerContext); 
    _operationLogRepository= new OperationLogRepository(_sqlServerContext); 
} 

[TestMethod] 
public void SomeTest() 
{ 
    // Arrange. 
    const int count = 10; 

    // Act. 
    var orders = _orderRepository.FindAll().Take(10).ToArray(); 

    // Assert. 
    Assert.IsNotNull(orders); 
    CollectionAssert.AllItemsAreNotNull(orders); 
    Assert.AreEqual(count, orders.Length); 
} 

một lần nữa, đó là tất cả các mã chưa được kiểm tra mà tôi chỉ cần gõ chữ lên, như tôi đã suy nghĩ về việc trả lời câu hỏi này.

HTH.

+0

Cảm ơn, điều này giúp ích rất nhiều. Vì vậy, cách duy nhất là thực sự chỉ có một bối cảnh ... và nếu tôi có 2 bối cảnh, thì tôi sẽ không có lựa chọn nào khác ngoài việc sử dụng một số cơ chế giao dịch, điều này có đúng không? – pdiddy

+0

không. bạn có thể có bao nhiêu tùy thích. chú ý rằng, với Dependency Injection, tôi đã nói HttpScopeOrThreadScope? Bạn có thể thay đổi đó để được singleton (ý tưởng tồi) hoặc mặc định đó là để 'mới' lên một trường hợp mới mỗi khi một đối tượng được yêu cầu.Vì vậy, nó thuộc vào bạn :) Nếu bạn làm theo cách thứ 2 (mà tôi đã làm bằng cách sử dụng một ví dụ thử nghiệm), sau đó yeah .. u sẽ phải tự mới lên mỗi bối cảnh, từng người một. ví dụ 'var context1 = new SSC (..); var context 2 = new SSC (...); _or = new OR (context1); _olr = new OLR (context2); 'etc .. –

+0

Tôi đã cập nhật câu trả lời của mình - tôi đã có một lỗi nghiêm trọng trong đó. Tôi thay thế bất kỳ tham chiếu đến một 'mới EntityConnection (connectionString)' với một 'connectionString' đồng bằng vì kết nối đã không được xử lý, nếu bối cảnh không tạo ra' EntityConection' (thay vì nhận được một thông qua vào nó). Chúc mừng đến Ayende Rahien (từ Hibernating Rhino's) để sửa chữa. –

Các vấn đề liên quan