2013-04-26 39 views
5

Tôi có hai bảng trong cơ sở dữ liệu của mình: TPM_AREASTPM_WORKGROUPS. Có tồn tại mối quan hệ nhiều-nhiều giữa hai bảng này và các mối quan hệ này được lưu trữ trong một bảng có tên là TPM_AREAWORKGROUPS. Bảng này trông như thế này:Có cách nào nhanh chóng để có được mọi liên kết giữa hai thực thể không?

enter image description here

Những gì tôi cần làm là tải tất cả các ánh xạ vào bộ nhớ cùng một lúc, theo cách nhanh nhất có thể. Như TPM_AREAWORKGROUPS là một hiệp hội, tôi không thể chỉ nói:

var foo = (from aw in context.TPM_AREAWORKGROUPS select aw); 

tôi có thể nghĩ ra ba cách để có thể làm được điều này, tuy nhiên tôi không hoàn toàn chắc chắn làm thế nào để hoàn thành mỗi trong số họ cũng không cái nào là tốt nhất.

1) tải trong mỗi nhóm làm việc, bao gồm các lĩnh vực liên quan đến:

Cái gì như:

var allWG = (from w in context.TPM_WORKGROUPS.Include("TPM_AREAS") 
      where w.TPM_AREAS.Count > 0 
      select w); 
// Loop through this enumeration and manually build a mapping of distinct AREAID/WORKGROUPID combinations. 

Ưu điểm: Đây có lẽ là cách EntityFramework tiêu chuẩn làm việc, và không đòi hỏi tôi thay đổi bất kỳ cấu trúc cơ sở dữ liệu hoặc ánh xạ nào.

Nhược điểm: Có khả năng chậm, vì bảng TPM_WORKGROUPS khá lớn và bảng TPM_AREAWORKGROUPS chỉ có 13 hàng. Ngoài ra, không có lớp học nào là TPM_AREAWORKGROUPS, vì vậy tôi phải trả lại một bộ sưu tập các Tuple hoặc tạo một lớp mới cho việc này.

2) Thay đổi mô hình của tôi

Lý tưởng nhất, tôi muốn một lớp TPM_AREAWORKGROUP, và một tài sản context.TPM_AREAWORKGROUP. Tôi đã sử dụng nhà thiết kế để tạo mô hình này trực tiếp từ cơ sở dữ liệu, vì vậy tôi không hoàn toàn chắc chắn cách buộc liên kết này là một mô hình thực tế. Có cách nào làm dễ hơn không?

Ưu điểm: Nó cho phép tôi chọn trực tiếp với bảng này, được thực hiện trong một dòng mã. Yay!

Nhược điểm: Buộc tôi thay đổi mô hình của mình, nhưng đây có phải là điều xấu không?

3) Vặn nó, sử dụng SQL thô để có được những gì tôi muốn.

Tôi có thể nhận được thuộc tính StoreConnection của ngữ cảnh và gọi trực tiếp CreateCommand(). Sau đó tôi có thể thực hiện:

using (DbCommand cmd = conn.CreateCommand()) 
{ 
    cmd.CommandText = "SELECT AreaId, WorkgroupId FROM TPM_AREAWORKGROUPS"; 
    var reader = cmd.ExecuteReader(); 
    // Loop through and get each mapping 
} 

Ưu điểm: Nhanh chóng, dễ dàng, không yêu cầu tôi thay đổi mô hình của mình.

Nhược điểm: Có vẻ như loại hacky. Ở mọi nơi khác trong dự án, chúng tôi chỉ sử dụng mã khung Entity chuẩn để điều này lệch khỏi định mức. Ngoài ra, nó có cùng các vấn đề như tùy chọn đầu tiên; vẫn không có lớp học TPM_AREAWORKGROUPS.

Câu hỏi: Giải pháp tốt nhất cho vấn đề này là gì?

Lý tưởng nhất, tôi muốn làm # 2 tuy nhiên tôi không hoàn toàn chắc chắn cách điều chỉnh mô hình của mình. Hoặc, có lẽ ai đó biết cách tốt hơn ba lựa chọn của tôi.

Trả lời

3

Bạn có thể làm:

var result = context 
    .TPM_WORKGROUPS 
    .SelectMany(z => z.TPM_AREAS.Select(z2 => new 
        { 
         z2.AREAID, 
         z.WORKGROUPID 
        })); 

SQL dịch sẽ là một đơn giản SELECT AREAID, WORKGROUPID FROM TPM_AREAWORKGROUPS.

Về lựa chọn khác:

  • tôi sẽ không sử dụng tùy chọn 3) bởi vì tôi personnally tránh SQL liệu càng nhiều càng tốt khi sử dụng Entity Framework (xem https://stackoverflow.com/a/8880157/870604 đối với một số lý do).

  • Tôi sẽ không sử dụng tùy chọn 2) vì bạn sẽ phải thay đổi mô hình của mình và có một cách đơn giản và hiệu quả để cho phép không thay đổi số.

+0

Ah, đây là một triển khai tuyệt vời của tùy chọn đầu tiên. Tôi nghĩ rằng điều này sẽ kết thúc là câu trả lời được chấp nhận .. –

+0

@MikeChristensen Tôi đã chỉnh sửa câu trả lời để cung cấp một số nhận xét về 2 tùy chọn khác. Tôi thực sự sẽ sử dụng LINQ cho các thực thể với mô hình hiện tại của bạn ở đây. – ken2k

0

Điều gì về việc sử dụng phép chiếu để tải dữ liệu?

Bạn có thể làm điều đó, hãy điền vào một đối tượng đồng nghĩa và sau đó làm việc với đối tượng theo cách bạn muốn.

+0

Mẫu mã xin vui lòng? –

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