2011-11-01 47 views
4

我遇到了一個奇怪的問題,使用CompiledQuery.Compile。當試圖用一個查詢中的靜態只讀場,我得到了以下錯誤消息:LINQ-SQL - 在CompiledQuery.Compile中使用靜態只讀字段?

Class member X is unmapped 

如果我移動領域decleration出部分類到不相關的LINQ-SQL另一個類,然後我得到以下內容:

Object reference not set to an instance of an object 

如果我通過穿過田野作爲參數,然後我看不出有任何錯誤和查詢工作正常,併產生預期的SQL。

一個例子是如下:

partial class Order 
{ 
    public static readonly string Complete = "Complete"; 
    public static readonly string Pending = "Pending"; 

    public static readonly Func<DataContext, Order, bool> IsComplete = 
     CompiledQuery.Compile((DataContext context, Order o) => 
      Complete == o.Status); 
} 

用法:

var test = from o in db.Orders 
      select new 
      { 
       IsComplete = Order.IsComplete(db, o) 
      }; 

這產生提到的錯誤。如果我添加一個string[]作爲CompiledQuery的另一個參數,那麼我看不到任何錯誤。另外,如果我將字符串修改爲const而不是static readonly,這也適用,但我想這是由於在編譯時分配了值。

有什麼辦法可以讓static readonly字段工作嗎?

+0

您是否嘗試使用'公共靜態只讀Func鍵 IsComplete = CompiledQuery.Compile((DataContext的上下文中,命令○)=> Order.Complete == o.Status);' –

+0

剛剛嘗試過,它給出:'類成員Order.X未映射'。 – Mig

+0

也許嘗試將所有三個字段改爲訪問器? 'public static string Complete {get {return「Complete」; }}'它是否給出了相同的結果? –

回答

2

問題發生是因爲Linq-To-Sql試圖將您的表達式轉換爲後端SQL,因爲邏輯發現它無法應對轉換它的未映射類成員。

我建議你創建一個包裝物業辦的工作你

partial class Order { 

    public static readonly string Complete = "Complete"; 
    public static readonly string Pending = "Pending"; 

    private static readonly Func<DataContext, Order, bool> _isComplete; 

    public static Func<DataContext, Order, bool> IsComplete { 
    get { 
     if (_isComplete == null) { 
     var complete=Complete; 
     _isComplete CompiledQuery.Compile((DataContext context, Order o) => 
                 complete == o.Status); 
     } 
     return _isComplete; 
    } 
    } 
} 

}

+0

不完全確定這是爲什麼起作用,但確實如此。另外,'Func'不允許只讀屬性。乾杯。 – Mig

+1

我已經從屬性調用中刪除了只讀(由太多的複製和粘貼引起)。這是工作的原因是因爲你最終傳遞一個局部變量到編譯lambda而不是實際的屬性。這允許LinqToSql正確評估它。 –

0

是沒有問題的,如果你不混合正常查詢和編譯查詢。下面的工作將會爲您提供更好的整體性能,但代價是無法重用您喜歡的任何地方編譯的簡單IsCompleted

public static readonly Func<YourDataContext, IEnumerable<Order>> GetCompletedOrders = 
    CompiledQuery.Compile((YourDataContext context) => 
     context.Orders.Where(o => Complete == o.Status));