2011-12-11 65 views
3

我有一個LINQ to SQL類,我們將其稱爲Test,我希望能夠通過LINQ查詢訪問屬性,但我得到着名的「No Supported Translation to SQL「運行時錯誤。我對概念問題感興趣。這裏是我的簡單類:Linq to SQL表達式屬性可轉換爲SQL

public class Test 
{ 
    public int ID {get; set;} // Stored in Database 
    public int NonForeignKeyValue {get; set;} // Stored in Database 
} 

這裏是有點什麼,我試圖完成一個例子,但我不希望總是明確地寫在LINQ的加入開銷:

var db = (new DataContext()).GetTable<Test>(); 
var q = (from t in db.GetTable<Test>() 
     join o in db.GetTable<OtherTable>() on o.ID equals t.ID 
     where t.OtherStuff 
     select t) 

我希望能夠將屬性添加到Test,告訴我是否有任何OtherTable行可與Test被連接:

public bool IsInOtherTable 
    { 
    get 
    { 
     return (new DataContext()) 
       .GetTable<OtherTabke>() 
       .Any(x => x.NonForeignKeyValue == this.NonForeignKeyValue)); 
    } 
    } 

最終這就是我想讓我的代碼看起來像,但它錯誤。我基本上要返回包含一些數據庫計算的值的所有條目:

using (DataContext db = new DataContext()) 
{ 
    var q = db.GetTable<Test>() 
      .Where(x => x.IsInOtherTable && x.OtherStuff); //Error 
}  

基本上,我試圖挽救自己從編寫這些代碼每一次我要檢查,如果測試有另一個表中的某些信息。我對我描述的確切問題並不感興趣,我更關心如何在概念上將連接部分添加到SQL中,並仍然使用LINQ。我猜我使用Linq.Expression,但我真的不知道,我不知道如何去做。另外,我可以寫出實際的SQL,因爲它並不那麼複雜,但我想知道如何解決這個問題並仍然使用LINQ。

編輯:我試過這個屬性,但我得到了同樣的錯誤。它更復雜,只是改變返回類型表達...

public System.Linq.Expressions.Expression<Func<Article3, bool>> Exists 
{ 
    get 
    { 
     using (DataContext db = new DataContext()) 
     { 
     return i => db.GetTable<OtherTable>() 
         .Any(x => x.NonForeignKeyValue == i.NonForeignKeyValue)); 
     } 
    } 
}   
+0

對於初學者你想一起使用的所有查詢必須使用相同的數據上下文 – BrokenGlass

+0

使用(...)塊嵌套到只有一個使用(...)塊嵌套嗎?這是如何運作的? – Mark

回答

0

首先,我想你可能高估「的總是明確地寫在LINQ的加入開銷」。這是一個額外的代碼行,它具有相對自我記錄的優點,就您正在做的事情而言(總是一件好事),其他任何方法都將首先轉化爲SQL,然後轉變爲查詢計劃至少與執行時一樣昂貴,可能更昂貴(SQLServer是一個很好的連接!)

儘管如此,還是有兩種我能想到的選擇。

一個是在定義與另一個表的關係的類上有一個EntityRef屬性。然後,您可以測試查詢中是否爲空(或EntitySet,如果它位於一對多關係的另一側)。

另一個是定義一個SQL函數,該函數返回bit結果,指示id是否引用了與另一個表相關的行。

然後在您的DataContext派生類上定義一個與C#中的簽名相匹配的受保護方法,並將Function attribute映射到該SQL函數。 (因爲這不是您可以在C#版本中提供明智的非數據庫版本的東西,所以您可以通過調用ExecuteMethodCall來實現C#函數)。

然後,您可以使用該方法,而不是加入。

儘管如此,這在代碼中可能不那麼明瞭,並且有可能比保持連接效率低。

+0

謝謝。我要去嘗試EntityRef路線。我的目標是儘可能多地抽象出複雜性,因爲我使用的是高度規範化的模式。我基本上試圖實現功能,然後如果(更像是什麼時候)有性能問題,我可以解決它們。這可能會落入後面需要解決的問題。 – Mark

1

每次LINQ發電機是將代碼轉換成一個查詢,它必須處理一個表達式樹。

在您的示例中,您並未傳遞表達式,而是 - 屬性,委託,即表達式訪問者無法「進入」的東西。

一般情況下,嘗試重新考慮你的條件,使代替bool你有Expression<T, bool>

http://netpl.blogspot.com/2008/02/linq-to-object-vs-linq-to-sql-and.html

+0

您的鏈接有關於Expression <>的一些信息,但它沒有解決您想要再次訪問數據庫的情況以獲取更多信息... – Mark