2012-02-23 34 views
5

Tôi đang sử dụng mẫu lưu trữ nơi tôi có một lớp kho lưu trữ trên mỗi bảng cơ sở dữ liệu. Tôi đã tự hỏi như thế nào các bạn tiếp cận các truy vấn mà chỉ cần phải trả lại một số cụ thể của cộtMẫu lưu trữ và kiểu trả về

Ví dụ nói rằng tôi có sau

mục Bảng (bảng hư cấu)

ItemId 
Name 
PurchaseDate 
Description 
Price 

Trong tôi code Tôi tạo một đối tượng với các trường ở trên được gọi là Item.cs (hiện không sử dụng orm).

Nếu tôi có nhiều tình huống mà tôi cần phải trở

  1. ItemID
  2. Một sự kết hợp của PurchaseDate và Tên
  3. ItemID và giá

Đó sẽ là phương pháp tốt nhất?

  1. Nhận tất cả các lĩnh vực từ bảng các mặt hàng và trả về một đối tượng mục (query 1 repo)
  2. Tạo ba truy vấn trong Repo và trả về một đối tượng mục cho mỗi một
  3. Tạo ba truy vấn trong Repo và chỉ trả lại những gì là cần thiết?

Bây giờ hãy tưởng tượng kịch bản này với một bảng có hơn 10 trường.

Cá nhân, tôi thích tùy chọn, nhưng tôi không chắc liệu có cách nào tốt hơn để thực hiện việc này hay không.

Trả lời

6

Cá nhân tôi sử dụng một kho lưu trữ kiểu chung chung và và có tôi đọc AsQueryable()

Dưới đây là giao diện.

interface IRepository<T> 
{ 
    void Create(T item); 
    IQueryable<T> Retrieve(); 
    void Update(T item); 
    void Delete(T item); 
    void SubmitChanges(); 
} 

và đây là cách triển khai.

public class PersonsRepository : IRepository<Person> 
{ 
    private DataContext dc; 

    public PersonsRepository(DataContext dataContext) 
    { 
     dc = dataContext; 
    } 

    public void Create(Person Person) 
    { 
     dc.Persons.Add(Person); 
    } 

    public IQueryable<Person> Retrieve() 
    { 
     IQueryable<Person> Person = (from s in dc.Persons 
             select s); 
     return Person.AsQueryable(); 

    } 

    public void Update(Person Person) 
    { 
     Person _Person = (from s in dc.Persons 
          where s.ID == Person.ID 
          select s).Single(); 
     { 
      _Person.LastLogin = Person.LastLogin; 
      _Person.Password = Person.Password; 
      _Person.LastUpdate = Person.LastUpdate; 
      // Cannot change your username. 
     } 
    } 

    public void Delete(Person Person) 
    { 
     dc.Persons.Remove(Person); 
    } 

    public void SubmitChanges() 
    { 
     dc.SaveChanges(); 
    } 
} 

Bây giờ nếu bạn cần truy vấn kho lưu trữ, bạn muốn làm điều gì đó như thế này.
tha thứ cho tôi, đoạn code dưới đây là chưa được kiểm tra và tôi thực sự chi tiết của một anh chàng VB :(
hy vọng bạn sẽ có được điểm

public class PersonsService 
{ 
    private PersonRepository<Person> personRepository; 

    public PersonService() 
    { 
     personRepository = new PersonRepository<Person>(); 
    } 

    public UsablePerson GetPersonByID(int ID) 
    { 
     UsablePerson person = (from p in personRepository<Person>.Retrieve 
           where p.ID = ID 
           select new UsablePerson { p.FirstName, 
                 p.LastName, 
                 p.EmailAddress }).FirstOrDefault(); 

     return person; 
    } 
} 

Đối với mục đích của tôi, tôi đang sử dụng LINQ trên đặc biệt này dự án, nhưng điều này có thể được điều chỉnh theo bất kỳ lớp dữ liệu nào bạn thích ... đó là vẻ đẹp của một lớp kho.

Từ đây tôi "cá nhân" cũng có Lớp dịch vụ liên quan đến các sắc thái của kết nối dữ liệu ... những thứ như GetPersonByID hoặc GetPeopleSince(DateTime marker). Đây là nơi tôi loại bỏ thông tin mà tôi không cần (IE: mật khẩu) và lưu trữ thông tin còn lại trong ViewModel hoặc một số POCO khác.

+0

Chỉ để xem tôi có đang ở cùng một trang hay không. Đối với các truy vấn cụ thể hơn như (GetPersonByID) bạn trả về toàn bộ bản ghi người từ Repo và sau đó trong lớp dịch vụ loại bỏ tất cả các thông tin không cần thiết và chỉ trả về ID? Bạn có thể cho thấy một ví dụ về điều này, bởi vì đây là những gì tôi đang gặp khó khăn với. Tôi không chắc liệu tôi có nên tạo ra nhiều phương thức Repo hay chỉ có một cột luôn trả về tất cả các cột trong bảng (tức là toàn bộ hàng). – chobo

+0

Tôi đã cố gắng hết sức từ bộ nhớ ... Tôi không có IDE trước mặt mình vì vậy có thể có một vài lỗi trong ví dụ trên. Hy vọng rằng bạn sẽ có được hình ảnh. –

+0

Tôi thích kỹ thuật đó vì nó cắt giảm số lượng phương thức trong kho. Tuy nhiên, tôi luôn được dạy rằng bạn chỉ nên trả lại các cột bạn cần từ một cơ sở dữ liệu có vẻ như với một Kho lưu trữ, bạn luôn luôn trả về một loại thực thể hoặc bộ sưu tập thực thể. Đó có phải là ý định của mẫu Repository không? Có lẽ tôi đang suy nghĩ về hiệu suất cơ sở dữ liệu tác động – chobo

0

Tôi thích kho lưu trữ dựa trên LINQ cho loại điều này.Linq2SQL, MSEF hoặc Linq2NH sẽ cho phép bạn, thông qua phương thức Select(), để xác định danh sách cột của bạn. Sau đó bạn sẽ nhận được một đối tượng miền hoặc lớp Entity chỉ được điền với những gì bạn đã chỉ định. Bạn có thể có mã bổ sung để ánh xạ bản đồ này vào DTO hoặc chỉ sử dụng lớp miền khi biết rằng nó không hoàn toàn "ngậm nước".

2

Nếu bạn nghĩ về Thiết kế điều khiển tên miền, thực tế một đối tượng duy nhất có cấu hình khác nhau nhiều khả năng chỉ ra các miền khác nhau. Điều này không đòi hỏi một đối tượng khác nhau cho mỗi đối tượng, nhưng nó là một mô hình tốt. Một cách để đạt được điều này là có một lớp cơ sở ith tập hợp các thuộc tính tối giản. Sau đó, bạn tạo thêm các lớp "miền cụ thể" kế thừa từ cơ sở.

Để trả lại dữ liệu, có nhiều cách khác nhau để "thu thập lưu lượng truy cập" luồng. Nhiều kho lưu trữ tách biệt ra các tên miền độc đáo, ví dụ. Nhưng điều này cho biết thêm sự phức tạp (không phải là một ý tưởng tốt trừ khi hoàn toàn cần thiết). Tôi không thích một kho lưu trữ nào trả về các đối tượng khác nhau. Nó là chấp nhận được hơn nếu bạn có một số tính chất nullable (có thể).

Tôi không thích LINQ to SQL như là một DAL, như @KethiS đã gợi ý, nhưng tôi làm việc trong môi trường doanh nghiệp và LINQ to SQL về cơ bản hút ở quy mô. Sử dụng LINQ nếu không thì rất tuyệt. Chỉ cần hai xu của tôi.

Nếu bạn có thể trả lại một loại đối tượng, điều đó tốt hơn. Nếu sự khác biệt trong các đối tượng dựa trên quyền, hãy xem xét xóa dữ liệu mà người dùng không thấy. Lưu ý, tuy nhiên, điều này không phải là khả năng mở rộng nếu bạn đang nắm lấy một số lượng lớn các đối tượng.

+0

+1 câu trả lời hay. – jgauffin

+1

Tôi có xu hướng chỉ trả về một loại đối tượng từ repo, nhưng những gì đang vấp ngã tôi là tôi luôn luôn trả về một đối tượng Entity? Ví dụ, nếu tôi có một phương thức gọi là GetEmployeeID, tôi có nên trả về một đối tượng Employee chỉ với trường đó không? Hoặc tôi có nên trả lại một số nhân viên không? Tôi có nên chỉ sử dụng một phương thức getEmployee hay tôi nên chia chúng thành các phương thức cụ thể hơn trong Repo như GetEmployeeId vs luôn luôn sử dụng GetEmployee? – chobo

5

Tôi thêm phương thức vào kho lưu trữ của mình khi tôi cần chúng ngược lại với kho lưu trữ chung nơi bạn nhận được tập hợp phương thức cho dù bạn có cần hay không.

Trả lại IQueryable là sự trừu tượng bị rò rỉ.

Hãy xem Thiết kế Driven miền (sách) và bạn sẽ có ý tưởng tốt về cách kho lưu trữ được thiết kế tốt như thế nào.

Tôi cũng đã viết một rant về kho chung: http://blog.gauffin.org/2012/02/generic-repositories-a-silly-abstraction-layer/

+0

Đồng ý, trả lại một 'IQueryable' đang làm hoàn toàn trái ngược với những gì bạn muốn một kho lưu trữ để làm - nó chỉ là mối quan tâm cơ sở hạ tầng đó trở lại vào lớp miền của bạn. – davenewza

0

Tại sao bạn sẽ trả lại tất cả các lĩnh vực khi bạn thực sự chỉ cần vài trong số họ? Chọn các trường mà bạn thực sự muốn nếu bạn lo lắng về hiệu suất. Tôi không phải là một fan hâm mộ lớn của đúng sau một mẫu thiết kế, có lẽ bạn nên xem xét thay đổi thiết kế theo yêu cầu của bạn.

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