2008-12-19 26 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(); 
      } 
     }