2013-07-22 58 views
0

我经历了类似的问题,但它力求解决我的目的。 我在2种方式中使用相同的代码:1.直接通过按钮按下2.通过计划任务。MVC3 - 一个实体对象不能被多个ientitychangetracker实例引用

通过方法1它工作正常,但方法2给出了该错误。 我的代码:

服务 -

public virtual int SendCampaign(Campaign campaign, EmailAccount emailAccount, 
     IEnumerable<NewsLetterSubscription> subscriptions) 
    { 
     var campaignSubscriberTrack = new CampaignNewsletterSubscriberTrack(); 

     if (campaign == null) 
      throw new ArgumentNullException("campaign"); 

     if (emailAccount == null) 
      throw new ArgumentNullException("emailAccount"); 

     int totalEmailsSent = 0; 

     foreach (var subscription in subscriptions) 
     { 
      var tokens = new List<Token>(); 
      _messageTokenProvider.AddStoreTokens(tokens); 
      _messageTokenProvider.AddNewsLetterSubscriptionTokens(tokens, subscription); 

      string subject = _tokenizer.Replace(campaign.Subject, tokens, false); 
      string body = _tokenizer.Replace(campaign.Body, tokens, true); 

      var email = new QueuedEmail() 
      { 
       Priority = 3, 
       From = emailAccount.Email, 
       FromName = emailAccount.DisplayName, 
       To = subscription.Email, 
       Subject = subject, 
       Body = body, 
       CreatedOnUtc = DateTime.UtcNow, 
       EmailAccountId = emailAccount.Id 
      }; 
      _queuedEmailService.InsertQueuedEmail(email); 
      totalEmailsSent++; 

      campaignSubscriberTrack.CampaignId = campaign.Id; 
      campaignSubscriberTrack.NewsletterSubscriberId = subscription.Id; 
      campaignSubscriberTrack.Campaign = campaign; 
      campaignSubscriberTrack.NewsletterSubscription = subscription; 
      campaignSubscriberTrack.IsEmailOpened = 0; 
      campaignSubscriberTrack.OpenedOnUtc = null; 
      Guid guid; 
      string id = tokens.Where(t => t.Key.Equals("TrackImage")).Select(t => t.Value).FirstOrDefault(); 
      var lastPart = (id.Split('/').Last()).Split('=').Last(); 
      if (lastPart != null) 
      { 
       guid = new Guid(lastPart); 
       campaignSubscriberTrack.ImageGUID = guid; 
      } 

      ***InsertCampaignNewsletterSubscriberTrack(campaignSubscriberTrack);*** 

     } 
     campaign.CampaignSchedulingTime = 0; 
     UpdateCampaign(campaign); 

     return totalEmailsSent; 
    } 

类 -

public partial class CampaignNewsletterSubscriberTrack 
    { 
     public virtual Campaign Campaign { get; set; } 
     public virtual int CampaignId { get; set; } 
     public virtual NewsLetterSubscription NewsletterSubscription { get; set; } 
     public virtual int NewsletterSubscriberId { get; set; } 
     public virtual int IsEmailOpened { get; set; } 
     public virtual DateTime? OpenedOnUtc { get; set; } 
     public virtual Guid ImageGUID { get; set; } 
    } 
} 

型号 -

public class CampaignNewsletterSubscriberTrackModel 
{ 
    public int CampaignId { get; set; } 

    public int NewsletterSubscriberId { get; set; } 

    public int IsEmailOpened { get; set; } 

    public DateTime? OpenedOnUtc { get; set; } 

    public Guid ImageGUID { get; set; } 
} 

而在此功能的一条记录被插入 -

public virtual void InsertCampaignNewsletterSubscriberTrack(CampaignNewsletterSubscriberTrack track) 
     { 
      if (track == null) 
       throw new ArgumentNullException("track"); 

      _campaignNewsletterSubscriberTrackRepository.Insert(track); 
     } 

错误发生在 - > InsertCampaignNewsletterSubscriberTrack(campaignSubscriberTrack); 我该怎么办? 任何人都可以告诉我哪里出错了吗?

回答

0

我猜你正在使用实体框架。并且您启用了更改跟踪。在这种情况下,实体对象存储对相应对象上下文的引用。

所以campaign,emailAccountsubscriptions在嫌疑人(如果他们真的是实体)。

而你通过campaignSubscriberTrack来引用这些实体,我猜你以后尝试添加到新的objectContext中。 带有外键的引用实体,或将它们附加到新的objectContext之前的分离实体。

更详细:

当你从数据库查询实体有几种方法其状态会受到影响。

如果您的实体(POCO我猜)不是密封类,并且包含虚拟导航属性和代理生成处于启用状态,则动态代理专门生成以修复实体关系。

如果标量属性也是虚拟的,那么除了这个DynamicProxy还有助于更改跟踪。

每个实体可以连接到上下文或从其分离。当您使用AsNoTracking()查询返回分离的实体。
正如您从异常中可以看到的,问题在于更改跟踪器。
因此,如果实体已连接到另一个实体并且打开了更改跟踪,则无法将该实体附加到上下文。

但是,如果更改跟踪已关闭:AsNoTracking()或代理未针对POCO生成(context.Configuration.ProxyCreationEnabled = false),则可以在上下文之间“共享”实体。

请注意,禁用propxies并不意味着返回分离的实体。它们将保持连接状态,但只有在调用DetectChanges()时才会在SaveChanges()中检测到更改。

所以这个例外应该告诉你,你用一个上下文没有处理的上下文来查询实体,然后尝试将实体图形附加到另一个上下文中。
而你必须在代码中使用新的上下文而不是旧的代码找到那个地方......或者在将它们附加到新的contex之前分离加载的实体。

+0

我不明白笏这意味着..你可以告诉我的一些例子?? –

+0

@supriyasalunkhe我更新了我的答案 –

相关问题