0

我遇到了类似的问题,但它解决了我的目的。我以两种方式使用相同的代码:1.直接通过按钮按下 2.通过计划任务。

通过方法 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); 我应该怎么办???谁能告诉我哪里出错了?

4

1 回答 1

0

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

所以campaign, emailAccount, 或被subscriptions怀疑(如果它们真的是实体)。

你引用了这些实体campaignSubscriberTrack,我猜你稍后会尝试通过这些实体添加到新的 objectContext 中。要么引用具有外键的实体,要么在将实体附加到新的 objectContext 之前分离实体。

更详细:

当您从数据库查询实体时,它的状态可能会受到多种影响。

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

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

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

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

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

因此,此异常应该告诉您,您使用一个未处理的上下文查询实体,然后您尝试将实体图附加到另一个上下文。
而且您必须在代码中找到使用新上下文而不是旧上下文的位置......或者在将它们附加到新上下文之前分离加载的实体。

于 2013-07-22T12:51:05.470 回答