0

2番目のコンテキストのIDを比較して、ターゲットコンテキストで作成されるエンティティのセットを作成しようとしています。

これは私が思いついたものですが、私はより良い方法を探しているか、これが正しい方法であることを確認しています。

これまでに指摘した主なポイントは次のとおりです。

  • クエリが複数のコンテキストを使用するときにエラーが発生しないようにするには、ToList()が必要です
  • 生成されたSQLにIN句を強制すると、処理できる数に上限があり、そのエラー条件が迫ってほしくないことを私は知っています。

    public override IEnumerable<Campaign> Execute()
    {
        using (var eom = eomDatabase.Create())
        using (var cake = cakeEntities.Create())
        {
            var campaigns = eom.Campaigns.Select(c => c.pid).ToList();
            var offers = cake.CakeOffers.Select(c => c.Offer_Id).ToList();
            var newOffers = offers.Except(campaigns).ToList();
            var newCampaigns = from offer in cake.CakeOffers
                               where newOffers.Contains(offer.Offer_Id)
                               select new Campaign {
                                   pid = offer.Offer_Id,
                                   campaign_name = offer.OfferName
                               };
    
            return newCampaigns.ToList();
        }
    }
    

更新:どうやらステートメントが私が思ったように機能しないようにします-私の元のコードがマルチコンテキストエラーを引き起こす間、上記はエラーを生成しません。

    var newCampaigns = from offer in cake.CakeOffers 
                       let campaigns = eom.Campaigns.Select(c => c.pid).ToList() 
                       let offers = cake.CakeOffers.Select(c => c.Offer_Id).ToList() 
                       let newOffers = offers.Except(campaigns).ToList() 
                       where newOffers.Contains(offer.Offer_Id) 
                       select new Campaign { 
                           pid = offer.Offer_Id, 
                           campaign_name = offer.OfferName 
                       }; 
4

1 に答える 1

1

1)ToList()の影響は、その時点でクエリが実行されることです。したがって、すべてのIDをメモリにプルしています。データセットの相対的なサイズに応じて、これは最適な場合と最適でない場合があります。ケーキのオファーよりも多くのキャンペーンがある場合は、最初にcakeEntitiesコンテキストを使用して、ケーキのオファーIDをメモリにクエリし、次にそれを破棄して残りを個別に管理する方がよい場合があります。

ケーキオファーの読み取りをバッチ処理することで、IN句の制限を簡単に回避できます。Take演算子を使用して一度に固定数を処理するだけです。

IList<int> cakeOffers;

using (var cakeDb = new cakeEntities())
{
    cakeOffers = cakeDb.CakeOffers.Take(10).Select(c => c.pid).ToList();        
}

2)(編集-あなたはこれを知っていたと思います...)あなたは実際にコンテキストで新しいキャンペーンを作成していません。あなたはただそれらの束をメモリに構築しているだけです。それらをコンテキストに追加し、保存して作成する必要があります。

編集

次に、Contains句を使用して、offer_Idsが一致する既存のキャンペーンについてeomDatabaseにクエリを実行します。例:

var existingCampaignOffers = campaignDb.Campaigns
    .Where(co => cakeOffers.Contains(co.Offer_Id)).Select(c => c.Offer_Id).ToList();

次に、最後にメモリ内のExcept()を使用して、新しいキャンペーンを作成するために必要な排他リストOffer_Idsを取得します。

于 2012-05-14T19:55:04.890 に答える