2012-12-21 17 views
6

Tôi đang làm việc với EF và có một số truy vấn. Đây là mã của tôiPhương thức tĩnh LINQ trong câu lệnh SELECT

IEnumerable<Customer> customers = from c in context.Customers 
    select new Customer 
    { 
     ID = c.ID, 
     Name = c.Name, 
     LastName = c.LastName, 
     DepID = c.DepID, 
     Editable = SomeStruct.Check(c.DepID) 
    } 

public struct SomeStruct 
{ 
    public static bool Check(int depID) 
    { 
     //Here I have some logic 
    } 
} 

Nó hoạt động tốt. Tuy nhiên, nếu tôi tuyên bố SomeStructclass thì sẽ không thành công.

Câu hỏi của tôi là:

  1. Tại sao nó xảy ra?
  2. Việc sử dụng chức năng tĩnh có buộc truy vấn thực thi không?
+9

tôi có thể xác nhận: nếu 'SomeStruct' là một' lớp', nhưng phương thức vẫn là 'tĩnh', thì nó * không * hoạt động - tôi có hiểu đúng không? Nếu vậy: chuyện gì xảy ra? Ngoại lệ là gì? –

+0

Bạn có thực sự chắc chắn rằng mã của bạn đang hoạt động khi SomeStruct là cấu trúc? Bạn có thể vui lòng thêm ToList() vào câu lệnh chọn của bạn và xem mọi thứ vẫn hoạt động không? –

Trả lời

0

Giả sử đó là vấn đề thời gian chạy, trong nhiều trường hợp bạn mô tả, đây là vấn đề tham chiếu. Nhà cung cấp LINQ của EF hỗ trợ gọi phương thức tĩnh được khai báo trong một lớp (tĩnh hay không).

  1. Tôi khuyên bạn nên thay đổi cấu trúc của mình thành một lớp VÀ làm cho nó tĩnh để giúp bạn điều tra vấn đề.

  2. Không, không có gì sẽ được thực hiện trước khi bạn gọi lặp lại đầu tiên hoặc khách hàng.

Hope this helps

6

Trong phương pháp mã của bạn SomeStruct.Check(c.DepID) nên được chuyển thành truy vấn SQL. Điều này mô tả hành vi với lớp/cấu trúc và vân vân. Đó là do công việc khác nhau của khung thực thể với các phương thức như vậy trong lớp và cấu trúc. Nhưng bạn có thể làm việc kiểm tra này trên client:

IEnumerable<Customer> customers = from c in context.Customers 
    select new 
    { 
     ID = c.ID, 
     Name = c.Name, 
     LastName = c.LastName, 
     DepID = c.DepID 
    } 
    .AsEnumerable() 
    .Select(d=>new Customer 
    { 
     ID = c.ID, 
     Name = c.Name, 
     LastName = c.LastName, 
     DepID = c.DepID, 
     Editable = SomeStruct.Check(c.DepID) 
    }); 

Hoặc bạn có thể thiết lập thuộc tính Editable là tài sản readonly:

public class Customer{ 
    public int ID{get;set;} 
    public string Name{get;set;} 
    public string LastName {get;set;} 
    public Guid DepID{get;set;} 
    public bool Editable{get{return SomeStruct.Check(DepID);}} 
} 
1

Nó có thể dễ dàng tái sản xuất rằng mã của bạn không thể làm việc với LINQ to Entities. Bất cứ điều gì mà không thể được dịch sang sql sẽ ném một ngoại lệ thời gian chạy. Trong trường hợp của bạn:

NotSupportedException: LINQ to Entities không nhận ra phương thức 'Phương thức Boolean Check (Int32)' và phương pháp này không thể được dịch sang biểu thức cửa hàng.

Nếu bạn đã nhận nó chạy ở một thời điểm nào, mà có thể không được liên quan đến struct hoặc class khác biệt, xem What's the difference between a static struct method and a static class method?

Bạn có thể thay đổi một cái gì đó khác cùng một lúc, giống như thêm ToList() trước select.