2008-12-19 68 views
4

在下面的代碼LINQ2SQL:管理的DataContext

public void Foo() 
{ 
    CompanyDataContext db = new CompanyDataContext(); 
    Client client = (select c from db.Clients ....).Single(); 
    Bar(client); 
} 

public void Bar(Client client) 
{ 
    CompanyDataContext db = new CompanyDataContext(); 
    db.Client.Attach(client); 
    client.SomeValue = "foo"; 
    db.SubmitChanges(); 
} 

該好好嘗試一下工作,我得到錯誤味精不起作用。 「試圖附加或添加一個不是新的實體,可能是從另一個DataContext加載的,這不被支持。」

你如何在整個應用程序中使用DataContexts,所以你不需要傳遞一個引用?

什麼

回答

4

PLINQO框架產生分離的所有實體使其易於分離並重新附加對象,而不會收到錯誤。

public void Foo() 
{ 
    CompanyDataContext db = new CompanyDataContext(); 
    Client client = (select c from db.Clients ....).Single(); 
    // makes it possible to call detach here 
    client.Detach(); 
    Bar(client); 
} 

public void Bar(Client client) 
{ 
    CompanyDataContext db = new CompanyDataContext(); 
    db.Client.Attach(client); 
    client.SomeValue = "foo"; 
    db.SubmitChanges(); 
} 

這裏是描述detach如何實現的文章。 http://www.codeproject.com/KB/linq/linq-to-sql-detach.aspx

0

我已經創建了一個封裝了所有與LINQ2SQL通信數據訪問類。 這些類有他們自己的datacontext,他們使用他們的對象。

public class ClientDataLogic 
{ 
    private DataContext _db = new DataContext(); 

    public Client GetClient(int id) 
    { 
     return _db.Clients.SingleOrDefault(c => c.Id == id); 
    } 

    public void SaveClient(Client c) 
    { 
     if (ChangeSetOnlyIncludesClient(c)) 
      _db.SubmitChanges(); 
    } 
} 

當然,只要需要對象,您就需要保持此對象的實例化。

檢查是否只有分辯對象已被更改爲altso有些bothersom,你可以做的方法,如

void ChangeClientValue(int clientId, int value); 

但可以成爲大量的代碼。

附加和分離是Linq2Sql中的一個有點缺失的功能,如果你需要使用很多,你應該使用Linq2Entities。

5

他們真的意味着 '這是不支持的。'。不支持附加到從另一個數據上下文獲取的對象。

這個問題有很多解決方法,推薦的方法是序列化對象,但這不是一件容易的事,也不是一種乾淨的方法。

最簡單的方法,我發現是使用一個只讀的DataContext爲獲取對象是這樣的:

 MyDataContext dataContext = new MyDataContext() 
     { 
      DeferredLoadingEnabled = false, 
      ObjectTrackingEnabled = false 
     }; 

從這種情況下獲得的對象可以連接到另一個環境,但只適用於某些情況下。

+0

會考慮這爲未來的LINQ到SQL項目。有關'一些情況'免責聲明的進一步信息? – 2011-09-29 06:15:36

+0

+1:這工作,但它看起來對我來說,你只需要`DeferredLoadingEnabled`或`ObjectTrackingEnabled`設置爲false,而不是他們兩個。我猜延遲加載依賴於對象跟蹤。 – 2012-04-09 10:51:47

0

您需要處理對象版本控制。

如果一個實體聲明瞭一個版本成員或者沒有更新檢查策略,那麼它只能在沒有原始狀態的情況下作爲修改被連接。因此,如果沒有提供時間戳成員或其他「版本控制」機制,那麼LINQ無法確定數據是否已更改 - 因此您看到的錯誤。

我解決了這個問題,我在表中添加了一個timestamp列,但還有其他方法。裏克斯特拉爾已經寫了一些體面的articles關於這個問題。

另請參閱thisthis了位更多信息。

+0

-1:這都是真的,但它與問題中的錯誤消息無關,這是由於將實體附加到源自另一個數據上下文的數據上下文所導致的。 – 2012-04-09 10:47:28

0

我看了看這個,發現它似乎只要原來的DataContext已經佈置精細的工作。

嘗試使用包裹的DataContext(),並確保您連接到第二的DataContext後發生的變化?它的工作對我來說..

 public static void CreateEntity() 
     { 
      User user = null; 
      using (DataClassesDataContext dc = new DataClassesDataContext()) 
      { 
       user = (from u in dc.Users 
         select u).FirstOrDefault();    
      } 
      UpdateObject(user); 
     } 

     public static void UpdateObject(User user) 
     { 
      using (DataClassesDataContext dc = new DataClassesDataContext()) 
      { 
       dc.Users.Attach(user); 
       user.LastName = "Test B"; 
       dc.SubmitChanges(); 
      } 
     }