2013-06-07 18 views
13

Tôi đang cố gắng hiểu các khái niệm cơ bản về Khung thực thể và tôi có câu hỏi về phương thức Set <> trên DbContext. Tôi đang sử dụng một mô hình cơ sở dữ liệu đầu tiên cho câu hỏi sau đây.Khuôn khổ thực thể: Khi nào sử dụng Set <>

Giả sử tôi có cơ sở dữ liệu ActivityLog, trong số những thứ khác tôi có thể sử dụng để rút ra một tin nhắn (ví dụ: thông điệp NLog). Tôi có thể viết một số mã để kéo ra khỏi tất cả các thư như thế này:

using (var entities = new ActivityLogEntities()) 
    foreach (var log in entities.AcitivityLogs) 
     Console.WriteLine(log.Message); 

Tuy nhiên tôi cũng có thể đạt được điều tương làm điều này:

using (var entities = new ActivityLogEntities()) 
    foreach (var message in entities.Set<ActivityLog>().Select(entity => entity.Message)) 
     Console.WriteLine(message); 

Câu hỏi của tôi là sự khác biệt giữa hai câu lệnh này là gì? Khi nào thì thích hợp hơn khi sử dụng cái kia? Hay đây chỉ là vấn đề sở thích cá nhân?

+1

Nếu bạn không có thuộc tính 'ActivityLogs', bạn không thể sử dụng thuộc tính' ActivityLogs'. Điều đó có vẻ giống như một phản ứng vô ích, nhưng tôi đã có những tình huống mà tôi cần truy cập vào một 'DbSet ' cho một loại cố ý không có thuộc tính trực tiếp cho các thực thể thuộc loại đó. Nhưng điều này không trả lời câu hỏi trong đó có thể sử dụng khi cả hai đều có thể. – hvd

+0

@hvd đã đồng ý nhưng khá hiếm khi có loại không được tham chiếu theo ngữ cảnh (và nó không hoàn toàn tầm thường để làm) –

+0

@LukeMcGregor Xem xét 'lớp công khai Đặt hàng {public ICollection Lines {get; bộ; }} public class OrderLine {} public class Context {public IDbSet Đơn đặt hàng {get; bộ tư nhân; }} '. Không cần thêm công việc nào để thực hiện công việc này, và nó thường không có ý nghĩa để truy cập 'OrderLines' mà không có đơn đặt hàng, vậy tại sao tôi nên thêm một thuộc tính' OrderLines' ở mức ngữ cảnh? – hvd

Trả lời

10

Không có sự khác biệt đáng kể. Trong trường hợp đầu tiên, bạn có cái gì đó như:

class MyContext : DbContext 
{ 
    public DbSet<AcitivityLog> AcitivityLogs { get; set; } 
} 

Khi bối cảnh được tạo ra, nó trông cho công chúng DbSet<T> read/write-tài sản, và thực hiện điều này (pseudo-code):

dbSetProperty = Set<EntityType>(); 

Nhưng , có những trường hợp, khi bạn:

1) không muốn tạo thuộc tính công khai cho tất cả các loại thực thể của bạn;
2) không biết tất cả các loại thực thể trong thời gian thiết kế của ngữ cảnh.

Trong những trường hợp này Set<T> là cách duy nhất để có được bộ thực thể phù hợp.

+0

Tôi đoán trong trường hợp ví dụ thứ hai của bạn, điều này chỉ áp dụng cho tự động được tạo? – Serberuss

+0

@Serberuss: không, không chỉ. Một trong những lợi ích của API 'DbContext' là bạn có thể xây dựng ngữ cảnh động (trái ngược với cách tiếp cận truyền thống với' ObjectContex' và thiết kế EDM). Điều này cho phép xây dựng mô hình dữ liệu linh hoạt hơn nhiều, nhưng nó có tác dụng phụ: danh sách các loại thực thể không tĩnh và nhà phát triển tổ tiên 'DbContext' không thể biết về mọi loại thực thể. – Dennis

+0

Thật không may là ví dụ thứ hai không hoạt động. Tôi theo loại lỗi: 'Thực thể không phải là một phần của mô hình cho ngữ cảnh hiện tại.' Tôi không biết mình đang làm gì sai. – krypru

1

Nếu bạn nhìn vào lớp DbContext được tạo, bạn sẽ thấy rằng AcitivityLogs chỉ là DbSet<ActivityLog>.

Vì vậy, chúng giống nhau. Nó chỉ là định nghĩa đánh máy của DbSet của bạn.

8

Lý do duy nhất tôi đã từng sử dụng Set<T> là khi bạn đang hành động trên một loại bạn không biết, ví dụ như một chèn chung.

Heres một ví dụ từ my generic repository:

public void AddOnSave(T entity) 
    { 
    ctx.Set<T>.Add(entity); 
    } 

Sử dụng nó cho các công cụ thông thường chỉ làm cho mã dễ đọc hơn IMHO

+0

['AddOrUpdate'] (https://msdn.microsoft.com/en-us/library/dn217945 (v = vs.113) .aspx)? – oCcSking

+0

@oCcSking không chắc chắn ý bạn là gì? –

+0

Thực ra, tôi không hiểu câu trả lời của bạn một cách chính xác, nhầm lẫn với trường hợp bạn không chắc chắn nếu bạn thêm hoặc cập nhật thì bạn có thể sử dụng AddOrUpdate – oCcSking

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