2013-07-22 4 views
0

Я прошел аналогичные вопросы, но это решает мою цель. Im, используя тот же код двумя способами: 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

Я предполагаю, что вы используете Entity Framework. И вы включили отслеживание изменений. В этой ситуации объект объекта хранит ссылку на соответствующий контекст объекта.

So campaign, emailAccount, или subscriptions под подозрением (если они действительно являются сущностями).

И вы ссылаетесь на эти сущности на campaignSubscriberTrack, которые вы позже пытаетесь добавить к новому объектуContext, я думаю. Либо ссылочные объекты с внешними ключами, либо отсоединяют объекты перед присоединением их к новому объектуContext.

Более подробно:

При запросе сущности из БД существует несколько способов его состояние может быть затронуты.

Если ваш объект (POCO, я думаю), не является закрытым классом и содержит виртуальный свойства навигации и создание прокси-сервера включены, динамический прокси генерируется специально для установления связей объектов.

Если скалярные свойства также являются виртуальными, то в дополнение к этому DynamicProxy помогает отслеживать изменения.

Каждая сущность может быть либо присоединена к контексту, либо к отдельной форме. Когда вы используете AsNoTracking(), запрос возвращает отдельные объекты.
Как вы можете видеть из исключения, проблема заключается в изменении трекера.
Таким образом, вы не можете прикреплять объект к контексту, если он уже привязан к другому, и изменение отслеживания включено.

Но если отслеживание изменений отключено: AsNoTracking() или прокси не создаются для POCOs (context.Configuration.ProxyCreationEnabled = false), вы можете делиться сущностью между контекстами.

Обратите внимание, что отключение propxies не означает возвращение отдельных объектов.Они останутся прикрепленными, но изменения будут обнаружены только при SaveChanges(), когда вызывается DetectChanges().

Таким образом, это исключение должно указывать на то, что вы запрашиваете разрешения с одним контекстом, который не оставлен, а затем вы пытаетесь присоединить граф объектов к другому контексту.
И вы должны найти это место в коде, где вместо старого используется новый контекст ... или отсоединить загруженные объекты, прежде чем присоединять их к новому контенту.

+0

Я не понял, что это значит .. Может ли сказать вам пример? –

+0

@supriyasalunkhe Я обновил свой ответ –