2013-07-22 52 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我更新了我的答案 –

相關問題