2013-01-17 14 views
8

Tôi có một dự án Khung thực thể có 5 bảng riêng biệt. Khi tôi truy vấn dữ liệu từ các bảng này và sử dụng .Include(), truy vấn mà nó tạo ra rất chậm và hết thời gian.Tôi đang thay đổi truy vấn EF linq của mình thành một thủ tục được lưu trữ. Có cách nào dễ dàng để thiết lập ánh xạ phức tạp?

Tôi đã di chuyển truy vấn đến một thủ tục được lưu trữ, và bây giờ đang tìm cách truy vấn thủ tục được lưu trữ này và dễ dàng ánh xạ dữ liệu mà nó trả về các lớp dữ liệu hiện có.

gốc LINQ truy vấn của tôi với DataContext của EF trông như thế này:

var data = (from a in context.A 
        .Include("B") 
        .Include("C") 
        .Include("D") 
        .Include("E") 
      where a.Id == someValue 
      select a); 

Nó trả về một đối tượng dữ liệu Entity rằng giống này:

class A 
{ 
    int Id; 
    string otherProperties; 

    List<B> B; 
    List<C> C; 
    List<D> D; 
    List<E> E; 
} 

Truy vấn rằng EF tạo ra để chạy trên SQL server trở lại tập hợp kết quả trông giống như sau:

 
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 
---------------------------------------------------------- 
A1 A2 B1 B2   
A1 A2    C1 C2 
A1 A2    C1 C2 
A1 A2    C1 C2 
A1 A2       D1 D2 
A1 A2       D1 D2 
A1 A2       D1 D2 
A1 A2          E1 E2 
A1 A2          E1 E2 

(giả định 1 bản ghi B, 3 bản ghi C, 3 bản ghi D và 2 bản ghi E.

Tôi đã sao chép truy vấn này trong một thủ tục được lưu trữ và giảm thời gian chạy của nó thành thực tế, tuy nhiên tôi đang cố gắng tìm cách lập bản đồ tập kết quả thành lớp dữ liệu Entity Framework (lớp A từ trên).

EF chắc chắn có khả năng này vì nó đã ở đâu đó đằng sau hậu trường khi tôi sử dụng truy vấn LINQ, nhưng tôi không chắc đó có phải là điều tôi có thể truy cập hay không.

Có cách nào dễ dàng trong khung thực thể để ánh xạ một thủ tục được lưu trữ (nhập hàm) cho một lớp khung Entity đa cấp không?

Trả lời

2

Tôi đã tìm thấy bài đăng trên blog giải thích cách thực hiện điều này bằng Khung thực thể.

http://blogs.infosupport.com/ado-net-entity-framework-advanced-scenarios-working-with-stored-procedures-that-return-multiple-resultsets/

Để tóm tắt nó một thời gian ngắn, bạn cần phải viết thủ tục lưu trữ của bạn để nó trả về dữ liệu của bạn một cách cụ thể mà được mong đợi của Entity Framework, và sau đó bạn có thể sử dụng một số EF extensions để tùy chỉnh thực hiện thủ tục lưu trữ của bạn và thực hiện biểu đồ đối tượng của bạn.Có vẻ như điều này được tích hợp vào khung Entity trong các phiên bản sau (5.0+ tôi tin), tuy nhiên cách giải quyết này có vẻ như nó sẽ hoạt động với các phiên bản thấp hơn.

Mặc dù trong trường hợp của mình, tôi tìm thấy nếu tôi vừa loại bỏ các truy vấn LINQ và tự kích hoạt tải các thuộc tính khác bằng cách tham chiếu chúng trong mã trước khi trả về đối tượng, vấn đề của tôi với hiệu suất đã được cố định. Điều này là do thay vì xây dựng một truy vấn lớn giữa 5 bảng với các phép nối không được tối ưu hóa, nó chạy 5 truy vấn riêng biệt mà mỗi truy vấn chỉ lấy dữ liệu cụ thể mà nó cần.

1

Khi tôi tối ưu hóa EntityFramework bằng cách chuyển đổi truy vấn tốn kém sang một storedprocedure, tôi tạo một lớp tùy chỉnh cho kết quả và sau đó thực hiện một số logic trong DbContext để chuyển lớp tùy chỉnh của tôi thành Entities.

Vì vậy, bạn muốn tạo ra một cái gì đó giống như

public class StoreProcARow 
{ 
public string Name {get;set;} // properties for every column 
} 

Và sau đó trong bạn DbContext

public A GetA(int ID) 
{ 
// do stored procedure 
IEnumerable<StoreProcARow> procResult = ... 
// process procResult into A type 

} 
+0

Đây là gói dự phòng của tôi nếu không có giải pháp thay thế dễ dàng nào được tích hợp vào EF. Có rất nhiều thuộc tính trên mỗi lớp, vì vậy sẽ có rất nhiều cách gõ mã để trình chuyển đổi. – Rachel

0

Hãy thử AutoMapper.

Bạn muốn làm điều gì đó như:

using AutoMapper; 

... 

Mapper.CreateMap<DataModel.B, ReplyObjects.B>; 
Mapper.CreateMap<DataModel.C, ReplyObjects.C>; 
... 
return new A 
{ 
    B = Mapper.Map<DataModel.B, ReplyObjects.B>(varContainingDataForB), 
    C = Mapper.Map<DataModel.C, ReplyObjects.C>(varContainingDataForC) 
    ... 
}; 

Chừng nào các thuộc tính trong ReplyObjects.B của bạn phù hợp với tên và loại của DataModel.B, mọi thứ sẽ lập bản đồ tự động!

+0

Điều đó có thể sẽ không hoạt động trong trường hợp của tôi, vì tập dữ liệu ban đầu của tôi chứa tất cả dữ liệu cho toàn bộ biểu đồ đối tượng và một số thuộc tính được đặt tên giống nhau (chẳng hạn như 'Id'). – Rachel

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