以下代码会导致删除而不是更新。
我的问题是:这是我对实体框架编码方式的错误还是我应该怀疑其他内容?
更新:我的工作正常,但我现在已经提出原始版本和工作版本的问题,希望我能学到一些我不了解的内容。 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)
或Find(pk)
方法可能会产生一些副作用?我应该咨询文档,但任何建议都表示赞赏..
答案 0 :(得分:1)
这是我的一个小小的假设(没有查看你的模型/实体),但看看这个块内发生了什么(看看这里附加的对象是否与删除有关):
if (db.Entry(target).State == EntityState.Detached)
{
db.SearchDailySummaries.Add(target);
addedCount++;
}
您的分离对象将无法使用其导航属性来查找其相关对象;你将重新附加一个处于潜在冲突状态的对象(没有正确的关系)。
你还没有提到上面被删除的内容,所以我可能会离开。刚离开,所以这有点匆忙,希望那里有一些有用的东西。