2012-12-21 121 views
6

我正在使用EF並且有一些查詢。這是我的代碼SELECT語句中的Linq靜態方法

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 
    } 
} 

它工作正常。 但是,如果我聲明SomeStructclass它將會失敗。

我的問題是:

  1. 它爲什麼會發生?
  2. 使用靜態函數是否強制查詢執行?
+9

我可以證實:如果'SomeStruct'是'class',但該方法仍然是'static',那麼它*不工作 - 我的理解是否正確?如果是這樣:會發生什麼?什麼是例外? –

+0

當SomeStruct是一個struct時,你確定你的代碼正在工作嗎?你能否將ToList()添加到你的select語句中,看看是否所有東西都還在工作? –

回答

0

假設這是一個運行時問題,在許多情況下您正在描述,這是一個參考問題。 EF的linq提供程序支持調用在類中聲明的靜態方法(靜態或非靜態)。

  1. 我建議你到你的結構改變爲一類,並使其靜態幫你調查這個問題。

  2. 不,在您調用第一次迭代或客戶之前不會執行任何操作。

希望這有助於

6

SomeStruct.Check(c.DepID)應轉化爲SQL查詢代碼的方法。這描述了類/結構等的行爲。這是由於實體框架在類和結構中使用這些方法的不同工作。但是你可以做此項檢查在客戶端:

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) 
    }); 

或者你也可以設置可編輯的屬性爲只讀屬性:

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

這是容易複製你的代碼不能使用LINQ工作的實體。 任何不能被翻譯成sql的東西都會拋出一個運行時異常。在您的情況下:

NotSupportedException:LINQ to Entities不能識別方法的布爾檢查(Int32)方法,並且此方法無法轉換爲存儲表達式。

如果你得到了它在一些點上運行,不能一直都跟structclass差異,請參閱What's the difference between a static struct method and a static class method?

你可能改變別的東西的同時,像select前添加ToList()