2

以下代码导致删除而不是更新。

我的问题是:这是我针对实体框架进行编码的方式中的一个错误,还是我应该怀疑其他东西?

更新:我得到了这个工作,但我现在将问题留在原始版本和工作版本中,希望我能学到一些我对 EF 不了解的东西。

在此,原始的非工作代码,当数据库是新鲜的,SearchDailySummary 对象的所有添加都成功,但是在第二次通过时,当我的代码应该执行更新时,最终结果是再次空表在数据库中,即这个逻辑设法是等价的。删除每个实体。

    //Logger.Info("Upserting SearchDailySummaries..");
    using (var db = new ClientPortalContext())
    {
        foreach (var item in items)
        {
            var campaignName = item["campaign"];

            var pk1 = db.SearchCampaigns.Single(c => c.SearchCampaignName == campaignName).SearchCampaignId;
            var pk2 = DateTime.Parse(item["day"].Replace('-', '/'));

            var source = new SearchDailySummary
            {
                SearchCampaignId = pk1,
                Date = pk2,
                Revenue = decimal.Parse(item["totalConvValue"]),
                Cost = decimal.Parse(item["cost"]),
                Orders = int.Parse(item["conv1PerClick"]),
                Clicks = int.Parse(item["clicks"]),
                Impressions = int.Parse(item["impressions"]),
                CurrencyId = item["currency"] == "USD" ? 1 : -1 // NOTE: non USD (if exists) -1 for now
            };

            var target = db.Set<SearchDailySummary>().Find(pk1, pk2) ?? new SearchDailySummary();
            if (db.Entry(target).State == EntityState.Detached)
            {
                db.SearchDailySummaries.Add(target);
                addedCount++;
            }
            else
            {
                // TODO?: compare source and target and change the entity state to unchanged if no diff
                updatedCount++;
            }

            AutoMapper.Mapper.Map(source, target);

            itemCount++;
        }

        Logger.Info("Saving {0} SearchDailySummaries ({1} updates, {2} additions)", itemCount, updatedCount, addedCount);
        db.SaveChanges();
    }

这是工作版本(虽然我不是 100% 它已经过优化,但只要我一次将 500 个或更少的项目批量处理,它就可以可靠地工作并且性能良好 - 之后它会成倍地减慢,但我认为只是可能是一个不同的问题/主题)......

    //Logger.Info("Upserting SearchDailySummaries..");
    using (var db = new ClientPortalContext())
    {
        foreach (var item in items)
        {
            var campaignName = item["campaign"];

            var pk1 = db.SearchCampaigns.Single(c => c.SearchCampaignName == campaignName).SearchCampaignId;
            var pk2 = DateTime.Parse(item["day"].Replace('-', '/'));

            var source = new SearchDailySummary
            {
                SearchCampaignId = pk1,
                Date = pk2,
                Revenue = decimal.Parse(item["totalConvValue"]),
                Cost = decimal.Parse(item["cost"]),
                Orders = int.Parse(item["conv1PerClick"]),
                Clicks = int.Parse(item["clicks"]),
                Impressions = int.Parse(item["impressions"]),
                CurrencyId = item["currency"] == "USD" ? 1 : -1 // NOTE: non USD (if exists) -1 for now
            };

            var target = db.Set<SearchDailySummary>().Find(pk1, pk2);
            if (target == null)
            {
                db.SearchDailySummaries.Add(source);
                addedCount++;
            }
            else
            {
                AutoMapper.Mapper.Map(source, target);
                db.Entry(target).State = EntityState.Modified;
                updatedCount++;
            }

            itemCount++;
        }

        Logger.Info("Saving {0} SearchDailySummaries ({1} updates, {2} additions)", itemCount, updatedCount, addedCount);
        db.SaveChanges();
    }

我脑海中不断浮现的事情是Entry(entity)orFind(pk)方法可能有一些副作用?我可能应该查阅文档,但任何建议都值得赞赏..

在此处输入图像描述

4

1 回答 1

1

It's a slight assumption on my part (without looking into your models/entities), but have a look at what's going on within this block (see if the objects being attached here are related to the deletions):

if (db.Entry(target).State == EntityState.Detached)
{
    db.SearchDailySummaries.Add(target);
    addedCount++;
}

Your detached object won't be able to use its navigation properties to locate its related objects; you'll be re-attaching an object in a potentially conflicting state (without the correct relationships).

You haven't mentioned what is being deleted above, so I may be way off. Just off out, so this is a little rushed, hope there's something useful in there.

于 2013-06-28T15:01:44.733 回答