2009-12-15 41 views
2

我有一個應用程序需要將多個數據庫中的表連接到一個LINQ-to-SQL查詢中。不幸的是,我爲每個數據庫都有單獨的DataContext類設置,所以這個查詢不起作用。我得到這樣的錯誤:「查詢包含對在不同數據上下文中定義的項目的引用」跨多個數據庫的DataContext

理想的解決方案似乎是爲所有三個數據庫創建單個DataContext。它們都存在於同一臺服務器上,因此它們可以使用相同的連接字符串。我目前使用運行sqlmetal.exe的腳本來生成我的DBML和CS文件,這意味着當我更改數據模型時,我不需要手動編輯任何文件。我想保持自動化水平,但sqlmetal.exe似乎只支持每個DBML文件的單個數據庫。

這可能與sqlmetal或其他工具?或者,我是否需要考慮另一種解決方案,如爲整個應用程序使用單個數據庫?

下面是我使用批處理文件腳本:

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SqlMetal.exe" /server:MYSERVER /database:DatabaseOne /views /functions /sprocs /dbml:DatabaseOne.dbml /namespace:Model.Domain.DatabaseOne /context:DatabaseOneDataContext /pluralize 
"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SqlMetal.exe" /server:MYSERVER /database:DatabaseOne /views /functions /sprocs /code:DatabaseOne.designer.cs /language:C# /namespace:Model.Domain.DatabaseOne /context:DatabaseOneDataContext /pluralize 

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SqlMetal.exe" /server:MYSERVER /database:DatabaseTwo /views /functions /sprocs /dbml:DatabaseTwo.dbml /namespace:Model.Domain.DatabaseTwo /context:DatabaseTwoDataContext /pluralize 
"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SqlMetal.exe" /server:MYSERVER /database:DatabaseTwo /views /functions /sprocs /code:DatabaseTwo.designer.cs /language:C# /namespace:Model.Domain.DatabaseTwo /context:DatabaseTwoDataContext /pluralize 

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SqlMetal.exe" /server:MYSERVER /database:DatabaseThree /views /functions /sprocs /dbml:DatabaseThree.dbml /namespace:Model.Domain.DatabaseThree /context:DatabaseThreeDataContext /pluralize 
"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SqlMetal.exe" /server:MYSERVER /database:DatabaseThree /views /functions /sprocs /code:DatabaseThree.designer.cs /language:C# /namespace:Model.Domain.DatabaseThree /context:DatabaseThreeDataContext /pluralize 
+0

我找到了一個可能適用於我的答案,但我仍然對更高級別的修補程序感興趣。換句話說,ubersqlmetal。 – MikeWyatt 2009-12-15 23:13:43

回答

2

一位同事發現a thread on another site [social.msdn.microsoft.com],討論同樣的問題。一個討論的解決方案是在「主」數據庫中執行視圖中的所有連接,並將這些視圖作爲應用程序中的對象公開。這可能適用於我的情況,因爲我的大部分數據都在一個數據庫中,而其他數據庫中的少量表是隻讀的。

1

這是要聽起來有點瘋狂,但我只是測試它,那麼試試這個:

  • 你要加入,或使用SqlMetal到「外部」表創建一個自定義實體類生成類;
  • 轉到TableAttribute,應該這樣說[Table(Name="dbo.ExternalTable")],並將其更改爲[Table(Name="DatabaseTwo.dbo.ExternalTable")]
  • 具有相同的名稱爲「DatabaseOne」 DataContext的創建一個部分類,並添加Table<T>財產存在,即:

    partial class DatabaseOneDataContext 
    { 
        public Table<ExternalTableRow> ExternalTable 
        { 
         get { return GetTable<ExternalTableRow>(); } 
        } 
    } 
    

現在嘗試運行整個查詢斷第一DataContext的:

DatabaseOneDataContext context = new DatabaseOneDataContext(); 
var query = from s in context.RealTable 
      join t in context.ExternalTable 
       on s.ID equals t.ID 
      select new { s, t }; 
Console.WriteLine(query.ToList().Count); 

令人難以置信的是,它的工作原理。這不是相當於就像使用SqlMetal一樣簡單,但您只需要編寫一次部分類,然後您就可以在兩個數據庫上運行SqlMetal,並將任何外部表的TableAttribute更改爲包含數據庫名稱。

這並不完美,但它有95%,不是嗎?

+0

這很有趣,但它仍然需要一些工作來完全自動化(如你所說)。如果在主數據庫中創建視圖失敗,我會給它一個鏡頭。 – MikeWyatt 2009-12-16 14:06:20

+0

您可以編寫一個簡短的腳本,您只需提供兩個CS文件(由SqlMetal生成)以及想要「導入」的表名稱,然後讓它自動生成部分類和實體。前者是一個文本模板,後者只是一個字符串。替換,所以你最終會得到完全自動化的東西。但是,如果您控制數據庫並且不介意創建跨數據庫視圖,那麼從長遠來看,這將更容易管理。 – Aaronaught 2009-12-16 15:21:55