更新导致System.NotSupportedException的LINQ to SQL对象

时间:2010-01-06 17:07:21

标签: linq linq-to-sql

当我想用子实体更新对象时,我得到System.NotSupportedException: An attempt has been made to Attach or Add an entity that is not new perhaps having been loaded from another DataContext

场景是这样的:

我有一个SubscriberProvider,允许我创建订阅者。

var provider = new SubscriberProvider(); // Creates a new repository with own datacontext

var newSubscriber = new Subscriber
{
   EmailAddress = emailAddress,
};

newSubscriber.Interests.Add(new Interest{
                              Id=1,
                              Name="cars"
                            });

provider.Subscribe(newSubscriber);

在正常的订阅页面上,这样可以正常工作。

现在我有一个linq2sql成员类(可以通过MemberRepository检索),我想扩展它以获得一个帮助器订阅方法,如下所示:

var repository = new MembershipRepository(); // Holds its own datacontext
var member = repository.Get("member1");

member.Subscribe(); // transfer member's info and interests to subscriber's table

SubscriberProvider尝试添加成员的兴趣时发生异常。 评论

newSubscriber.Interests.Add(new Interest{
                              Id=1,
                              Name="cars"
                            });

将使member.Subscribe()有效。

member.Subscribe()就是:

    public void Subscribe(bool emailIsVerified, bool receiveEmails, bool sendDoubleOptIn)
    {
        var provider = new MailingListProvider();

        provider.Subscribe(EmailAddress, emailIsVerified, receiveEmails, CountryId, sendDoubleOptIn, ConvertInterests(MemberInterests.ToList()));  
    }

那么当我执行member.Subscribe()以及如何解决这个问题时,是什么导致子实体(Interests)丢失了他们的datacontext?

3 个答案:

答案 0 :(得分:0)

似乎这里缺少一些代码,但无论如何我会采取刺激措施,因为我觉得我知道发生了什么。

如果您为MembershipRepository和SubscriberRepository创建了不同的DataContext,那么您将遇到与已从另一个DataContext加载的实体相关的问题。 (正如你发布的Exception指出的那样)。您不能只从一个DataContext中取出一个对象并将其保存到另一个DataContext中。

看来你可能在这里遇到了一个架构问题。这两个存储库是否应该分开?如果是这样,他们应该有完全不同的DataContexts吗?我可能会建议使用依赖注入将DataContexts注入您的存储库。然后,您可以决定如何缓存DataContexts。

答案 1 :(得分:0)

您注释掉的那行代码被DataContext标记为新记录,即使由于错误消息,该记录可能已经存在。

将行更改为:

newSubscriber.Interests.Add(DataContext.Interests.Where(a => a.Id == 1).Single());

现在,DataContext将知道该记录是已存在的记录,并且不会尝试将其作为Insert添加到ChangeSet。

答案 2 :(得分:0)

自己找到解决方案。事实证明,导致它的是ConvertInterests()方法。转换后的兴趣对象有一个无效的声明,编译好。

认为代码很简单,我没有为它创建测试。我应该知道的更好!