2016-05-20 14 views
7

EF là tạo SQL khác nhau cho cho hai câu lệnh tương tự như liệt kê dưới đâyEF SQL thay đổi khi đi qua vị như Parameter để ở đâu khoản

var test = dbcontext.Persons.GetAll() 
          .Where(c => c.PersonID == 2) 
          .Select(c => c.PersonName) 
          .FirstOrDefault();` 

SQL tạo:

SELECT 
    [Limit1].[PersonName ] AS [PersonName ] 
FROM 
    (SELECT TOP (1) 
     [Extent1].[PersonName ] AS [PersonName ] 
    FROM 
     [dbo].[ApplicationRequest] AS [Extent1] 
    WHERE 
     [Extent1].[PersonID ] = @p__linq__0) AS [Limit1]',N'@p__linq__0 uniqueidentifier',@p__linq__0= "2" 

Tôi đang sử dụng những điều khoản trên tại nhiều nơi có điều kiện khác nhau Where; để củng cố logic trong một nơi tôi đi qua tình trạng này như một tham số

Public Void PassPredicate(Func<ApplicationRequest, bool> ReqFunc) 
{ 
    var test = dbcontext.Persons.GetAll() 
           .Where(ReqFunc) 
           .Select(c => c.PersonName) 
           .FirstOrDefault(); 
} 

tôi kêu gọi các chức năng như

PassPredicate(c => c.PersonID == 2); 

tạo SQL:

SELECT 
    [Extent1].[PersonID] AS [PersonID], 
    [Extent1].[PersonName ] AS [PersonName ], 
    [Extent1].[DOB] AS [Dob], 
    [Extent1].[Height] AS [Height], 
    [Extent1].[BirthCity] AS [BirthCity], 
    [Extent1].[Country] AS [Country], 
FROM 
    [dbo].[Person] AS [Extent1] 

Nếu bạn nhìn vào thứ hai SQL, nó khá đáng báo động: nó đang kéo tất cả thông tin (cột và hàng). Nó không có mệnh đề where và chọn tất cả các cột.

Điều kiện ở đâu đang được áp dụng sau khi kết quả được trả về từ DB.

Sự khác biệt duy nhất trong câu lệnh thứ hai là tôi đang chuyển điều kiện làm tham số thay vì có điều kiện bên trong mệnh đề where.

Bất cứ ai có thể giải thích lý do tại sao sự khác biệt?

+0

'var test = dbcontext.Persons.GetAll(). Ở đâu (c => c.PersonID == 2) .Chọn (c => c.PersonName) .irstOrDefault();' tại sao bạn không sử dụng câu lệnh đơn giản như 'var test = dbcontext.Persons.FirstOrDefault (c => c.PersonID == 2) .Chọn (c => c.PersonName);' –

+0

Tôi bị ràng buộc một chút khi sử dụng ngoài GetALL. Thực ra chúng tôi không sử dụng chính xác cú pháp .. chúng tôi đang sử dụng một cái gì đó giống như PersonsRepository.GetAll() ... Kho lưu trữ chỉ hiển thị các chức năng giới hạn –

+0

oky nhưng tôi nghĩ rằng nó sử dụng thêm tài nguyên. –

Trả lời

6

Kể từ ReqFunc loại là Func<ApplicationRequest, bool> bạn đang sử dụng Enumerable phần mở rộng, do đó, mã của bạn (Where, Select, FirstOrDefault) sẽ được thực hiện trong bộ nhớ.

Để sửa lỗi này, chỉ cần thay đổi ReqFunc để Expression<Func<ApplicationRequest, bool>> sử dụng Queryable phần mở rộng:

Public Void PassPredicate(Expression<Func<ApplicationRequest, bool>> ReqFunc) 
{ 
    var test = dbcontext.Persons.GetAll().Where(ReqFunc).Select(c => c.PersonName).FirstOrDefault(); 
} 
+1

Đã làm việc..Đó là lý do tại sao bạn phải hiểu kỹ khái niệm trước khi đi vào mã hóa ... thay vì nhận các giải pháp tức thì thông qua tràn ngăn xếp..Tôi ghét làm điều đó ... nhưng tôi vẫn đang làm điều đó;) –

0

Các IQueryable đâu mất một Expression<Func<TSource, bool>>, KHÔNG một Func<TSource, bool>, do đó, một tình trạng quá tải khác nhau ở đâu được gọi là, làm cho truy vấn để thực thi và kết quả được trả về dưới dạng một IEnumerable thay vì một IQueryable.

public static IQueryable<TSource> Where<TSource>(
this IQueryable<TSource> source, 
Expression<Func<TSource, bool>> predicate 
) 

Chuyển Func thành Biểu thức và bạn sẽ có được hành vi mong muốn.

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