2012-03-20 73 views
2

在我以前的應用程序中,當我使用linq-to-sql時,我總是使用一個類來放入我的linq-to-sql代碼,所以我只有一個DataContext從另一個DataContext加載?

我目前的應用雖然越來越太大了,我開始在不同的班級了分裂我的代碼(一個客戶,一個地點,一個供應商......),他們都有自己的DataContext DatabaseDesignDataContext dc = new DatabaseDesignDataContext();

現在,當我嘗試保存位置的接觸(這是我從一個不同的DataContext了)我得到以下錯誤:

"An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported."

我想這是因爲我創造了每個類別的DataContext,但我不會」你知道如何做到這一點嗎?

我在找任何想法,謝謝。

我班如下所示:

public class LocatieManagement 
{ 
    private static DatabaseDesignDataContext dc = new DatabaseDesignDataContext(); 

    public static void addLocatie(locatie nieuweLocatie) 
    { 
     dc.locaties.InsertOnSubmit(nieuweLocatie); 
     dc.SubmitChanges(); 
    } 

    public static IEnumerable<locatie> getLocaties() 
    { 
     var query = (from l in dc.locaties 
        select l); 
     IEnumerable<locatie> locaties = query; 

     return locaties; 
    } 

    public static locatie getLocatie(int locatie_id) 
    { 
     var query = (from l in dc.locaties 
        where l.locatie_id == locatie_id 
        select l).Single(); 

     locatie locatie = query; 
     return locatie; 

    } 
} 

回答

-2

另一種解決方案,我發現這是創建一個父類DataContext

public class DataContext 
{ 
    public static DatabaseDesignDataContext dc = new DatabaseDesignDataContext(); 
} 

,讓我的所有其他類繼承這一塊。

public class LocatieManagement : DataContext 
{ 
     public static void addLocatie(locatie nieuweLocatie) 
     { 
      dc.locaties.InsertOnSubmit(nieuweLocatie); 
      dc.SubmitChanges(); 
     } 
} 

然後所有的類都使用相同的DataContext。

+0

如果你想做任何交易處理(你應該這樣做),這是一個壞主意。此外,如果使用多個線程或者它是一個Web應用程序,當多個線程嘗試使用相同的數據上下文時,您將遇到問題。這也防止了多個同時使用的數據庫連接被使用,因此一切都依賴於相同的連接。 – 2012-06-22 12:55:27

+0

謝謝,我不知道交易處理是什麼。你會如何解決這個問題? – Schoof 2012-06-22 14:41:49

+0

我的意思是你應該創建一個新的DataContext並在執行某些工作時使用它。然後擺脫它(在'using(MyDataContext dc = new MyDataContext())'塊中做你的工作)。不要使用全局數據上下文 - 爲每個需要做的事情創建一個全新的數據上下文。例如,如果您正在加載網頁數據,請爲該頁面視圖使用單個數據上下文。如果您正在執行所有步驟相互關聯和相互依賴的多步操作,那麼也應爲整個流程使用單一數據上下文。希望這可以幫助! – 2012-06-22 19:11:31

0

我知道大家可能厭倦聽到這個,但你真的應該看看使用存儲庫數據訪問(和使用工作模式的單位,以確保所有共享工作單元的存儲庫都使用相同的DataContext)。

您可以閱讀如何在這裏做的事情:Revisiting the Repository and Unit of Work Patterns with Entity Framework(同樣的概念也適用於LINQ to SQL)。

+0

謝謝,我不是很熟悉Interfaces/Repositories,我會嘗試閱讀你提供的鏈接。 – Schoof 2012-03-20 13:49:02

+0

這個答案是「去讀其他的東西」 - 一個榮耀的鏈接唯一的答案。它不直接提供任何有用的信息。 – SAJ14SAJ 2015-07-08 18:56:09

1

如果實體仍附加到原始數據環境,則會發生這種情況。關閉延遲加載(dc.DeferredLoadingEnabled = FALSE):

partial class SomeDataContext 
{ 
    partial void OnCreated() 
    { 
     this.DeferredLoadingEnabled = false; 
    } 
} 

您可能還需要序列化/(例如,使用的DataContractSerializer)從原來的DC斷開一次反序列化,下面是使用DataContractSerializer的克隆方法:

internal static T CloneEntity<T>(T originalEntity) where T : someentitybaseclass 
{ 
    Type entityType = typeof(T); 

    DataContractSerializer ser = 
     new DataContractSerializer(entityType); 

    using (MemoryStream ms = new MemoryStream()) 
    { 
     ser.WriteObject(ms, originalEntity); 
     ms.Position = 0; 
     return (T)ser.ReadObject(ms); 
    } 
} 
+0

是否必須關閉每個課程中的緩衝加載?謝謝。 – Schoof 2012-03-20 13:47:59

+0

如果你不使用延遲加載/延遲加載,你可以通過將它添加到datacontext的OnCreated中來關閉它(我將用這個示例更新我的答案) – KristoferA 2012-03-21 01:02:06

1

這是因爲你想從不同環境管理數據 - 你需要正確地分離和附加你的對象進行 - 不過,我會建議防止需要做到這一點。

所以,首先要做的第一件事:從實體類中刪除數據上下文實例。

從這裏創建「業務」類,暴露CRUDs和諸如此類的東西與該特定類型的實體類的,其中,每個功能使用專用數據上下文爲單元工作的工作,也許超載接受當前上下文因爲當一個工作單元需要後續操作時。

+0

我不是當然,我明白你的操作類意味着什麼。我用一個班級的例子更新了我的第一篇文章。 你的意思是說我應該使用類似繼承的東西? 感謝您的幫助! – Schoof 2012-03-20 13:50:57

+0

對不起術語混淆,但實踐就像賈斯汀的建議:使用回購模式,其中回購接受和返回類型的實體,去數據庫得到它們(或如果您的回購實現這樣的事情從緩存中)並將它們一舉設定,最後關閉數據上下文。 – 2012-03-20 13:57:41

+0

我明白了,遺憾的是我並不知道如何做到這一點。我從來沒有使用過接口或回購模式。 (我還在學習) 我會試着看看它,謝謝。 :) – Schoof 2012-03-20 14:10:09