2

次のコードでは、更新ではなく削除が行われます。

私の質問は、これは Entity Framework に対してコーディングしている方法のバグですか、それとも何か他のことを疑うべきですか?

更新:私はこれを機能させましたが、EFについて理解していないことを学べることを期待して、元のバージョンと機能するバージョンの両方で質問を残しています。

これでは、元の非動作コードでは、データベースが新しい場合、SearchDailySummary オブジェクトのすべての追加が成功しますが、2 回目は、私のコードが更新を実行しようとしていたとき、最終的な結果は再び空のテーブルになります。データベース内、つまり、このロジックは同等であることが管理されています。各エンティティを削除します。

    //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

これは私の側のわずかな仮定です (モデル/エンティティを調べずに) が、このブロック内で何が起こっているかを見てください (ここに添付されているオブジェクトが削除に関連しているかどうかを確認してください):

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

切り離されたオブジェクトは、ナビゲーション プロパティを使用して関連オブジェクトを見つけることができません。競合する可能性のある状態 (正しい関係なし) でオブジェクトを再アタッチします。

上記で何が削除されるかについて言及していないので、私はかなりずれているかもしれません。ちょうど出発したばかりなので、これは少し急いでいます。そこに何か役立つものがあることを願っています.

于 2013-06-28T15:01:44.733 に答える