2013-03-21 28 views
12

Tôi đang sử dụng EF (phiên bản dll là 4.4) để truy vấn cơ sở dữ liệu. Cơ sở dữ liệu chứa một số bảng có thông tin khóa học. Khi có một cái nhìn những gì thực sự được gửi đến db tôi thấy một lớn, gần như 1300 dòng truy vấn SQL (mà tôi sẽ không dán ở đây vì kích thước của nó). Truy vấn Tôi đang chạy vào bối cảnh trông giống như:Làm cách nào để tránh các truy vấn SQL được tạo lớn trong EF khi sử dụng Include()

entities.Plans 
    .Include("program") 
    .Include("program.offers") 
    .Include("program.fees") 
    .Include("program.intakes") 
    .Include("program.requirements") 
    .Include("program.codes") 
    .Include("focuses") 
    .Include("codes") 
    .Include("exceptions") 
    .Include("requirements") 
where plans.Code == planCode 
select plans).SingleOrDefault(); 

Tôi muốn tránh phải đi lại cho máy chủ khi thu thập thông tin từ mỗi của các bảng liên quan nhưng với một truy vấn lớn như vậy tôi tự hỏi nếu có cách nào tốt hơn để làm điều này?

Cảm ơn.

+0

Vâng, bạn đang thực hiện tải mong muốn và truy vấn của bạn đang cố gắng thu thập tất cả dữ liệu cùng một lúc, vì vậy tại sao nó lại lớn. Chính xác những gì bạn thấy là một vấn đề ở đó?Tùy chọn khác là tải lười biếng với các thuộc tính ảo, nó sẽ được lấy trong nền của EF khi bạn cố gắng truy cập chúng, nhưng bạn đã chỉ rõ bạn không muốn roundtrips vào cơ sở dữ liệu. –

+0

Có một loại câu trả lời tương tự ở đây http://stackoverflow.com/questions/5521749/how-many-include-i-can-use-on-objectset-in-entityframework-to-retain-performance –

+0

Tôi đoán là tự hỏi nếu tôi đang xem xét điều này một cách chính xác. Một truy vấn lớn so với một số truy vấn nhỏ hoặc liệu có cách nào tốt hơn để thực hiện việc này hay không. – b3n

Trả lời

0

Bạn thường có thể thêm .Include() sau mệnh đề where. Điều này có nghĩa là bạn chỉ lấy thông tin phù hợp với những gì bạn muốn, xem liệu điều đó có làm giảm truy vấn của bạn hay không.

+1

Điều này không tạo sự khác biệt. Tôi chạy truy vấn trong LINQPad và SQL được tạo ra là giống nhau trong cả hai trường hợp. – b3n

+0

'sau' mệnh đề where và nó vẫn như cũ? Có vẻ lạ ... Chỉ có một điều khác tôi có thể gợi ý là thử các thuộc tính điều hướng, tôi tin rằng chúng hoạt động hơi khác, nhưng tôi thành thật không hiểu hết chúng. Cách khác, bạn có thể lấy thông tin từ bảng kế hoạch, với mệnh đề bộ lọc/vị trí. Sau đó chạy một vài câu lệnh nối để có được những gì bạn cần. Mã không phải là khá ngắn gọn, nhưng nó sẽ tăng tốc độ lên. – Trent

0

Khi bạn đang thực hiện quá trình tải mong muốn, vì vậy nếu bạn đang chọn các thực thể bắt buộc thì đó là tiền phạt. Nếu không, bạn có thể đi với tải Lazy, nhưng khi bạn chỉ định rằng bạn không muốn cơ sở dữ liệu vòng chuyến đi, vì vậy bạn có thể tránh nó.

Tôi sẽ đề xuất, Nếu truy vấn này được sử dụng nhiều lần thì bạn có thể sử dụng truy vấn được biên dịch. Vì vậy, nó sẽ tăng hiệu suất.

Đi qua liên kết này, nếu bạn muốn .. http://msdn.microsoft.com/en-us/library/bb896297.aspx

0

Nếu bạn đang sử dụng DbContext, bạn có thể sử dụng .Local tài sản trên bối cảnh để xem xét nếu tổ chức của bạn đã được lấy ra và do đó gắn liền với bối cảnh .

Nếu truy vấn đã chạy trước và rễ Plan thực thể của bạn được đã được gắn dựa trên Plan.Code == planId, có lẽ tiểu đơn vị của nó cũng đã gắn liền kể từ khi bạn đã tải háo hức, vì vậy đề cập đến chúng thông qua các thuộc tính điều hướng sẽ không nhấn DB cho họ một lần nữa trong suốt cuộc đời của bối cảnh đó.

Điều này article có thể hữu ích khi sử dụng .Local.

0

Bạn thể có thể nhận được một truy vấn SQL hơi ngắn gọn hơn bằng cách sử dụng chiếu chứ không phải Include để kéo trở lại đơn vị tham chiếu của bạn:

var planAggregate = 
(from plan in entities.Plans 
    let program = plan.Program 
    let offers = program.Offers 
    let fees = program.Fees 
    //... 
    where plan.Code == planCode 
    select new { 
    plan 
    program, 
    offers, 
    fees, 
    //... 
    }) 
    .SingleOrDefault(); 

Nếu bạn tắt tải lười biếng trên ngữ cảnh của bạn như thế này truy vấn sẽ dẫn đến thuộc tính điều hướng của các thực thể của bạn được điền với các thực thể được bao gồm trong truy vấn của bạn.

(Tôi chỉ thử nghiệm điều này trên EF.dll v5.0, nhưng nó sẽ hoạt động tương tự trên EF.dll v4.4, chỉ là EF5 trên .NET 4.0. Khi tôi thử nghiệm bằng mẫu này thay vì Include trên truy vấn có hình dạng tương tự, nó cắt khoảng 70 dòng trong số 500 dòng SQL. Số dặm của bạn có thể thay đổi.)

1

Một chút trễ nhưng dữ liệu của bạn chỉ thay đổi mỗi ngày, hãy xem mọi thứ bạn cần một khung nhìn được lập chỉ mục và đặt khung nhìn này trong mô hình EF của bạn.

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