1

私はデータベースとしてMssqlを、ORM/DALとしてEF4を使用しています。
私の質問は、次のコードについてです:削除する前に行が存在するかどうかを確認する必要がありますか?

public static void DeleteBuilding(int buildingId, int countryId) 
{ 
    PlayerBuilding playerBuilding = new PlayerBuilding() 
    { 
     CountryID = countryId, 
     BuildingID = buildingId 
    }; 
    Entities.PlayerBuildings.Attach(playerBuilding); 
    Entities.PlayerBuildings.DeleteObject(playerBuilding); 
    Entities.SaveChanges(); 
} 

行は、これは非常にうまく機能が存在する場合、私は例外を取得しない場合ストアUPDATE、INSERT、またはステートメントが行の予想外の数に影響を与え削除します(0)エンティティがロードされたので、エンティティが変更または削除された可能性がありエントリをObjectStateManagerリフレッシュ
私は、行はこのように存在するかどうかを確認するために、データベースへのラウンドトリップを行う必要があります。。。

public static void DeleteBuilding(int buildingId, int countryId) 
{ 
    PlayerBuilding playerBuilding = (from p in Entities.PlayerBuildings 
            where p.BuildingID == buildingId && p.CountryID == countryId 
            select p).FirstOrDefault(); 
    if (playerBuilding != null) 
    { 
     Entities.PlayerBuildings.DeleteObject(playerBuilding); 
     Entities.SaveChanges(); 
    } 
} 

私は余分な往復が必要ないと思います。なぜなら、EFなしでは、単純なSQLを使用すると、単純に1つのDELETEコマンドで行を削除できるからです。

もっと良い方法はありますか?

答えて

0

このエラーは、Entity Frameworkのオプティミスティック同時実行の副作用です。

基本的に、他の人があなたの検索の間にそのレコードを削除している可能性があります。あるいは、あなたはそのコードの前にエンティティで何かをしているかもしれません。

問題がまだ発生しているかどうかを確認するには、隔離環境(ユニットテストなど)で実行してみてください。

はい、あなたはそれを安全にプレーして、再度レコードを取得、またはあなたがObjectContext.Refresh使用することができますことができます:サイドノートでは

public static void DeleteBuilding(int buildingId, int countryId) 
{ 
    PlayerBuilding playerBuilding = new PlayerBuilding() 
    { 
     CountryID = countryId, 
     BuildingID = buildingId 
    }; 

    try 
    { 
     Entities.PlayerBuildings.Attach(playerBuilding); 
     Entities.PlayerBuildings.DeleteObject(playerBuilding); 
     Entities.SaveChanges(); 
    } 
    catch (OptimisticConcurrencyException) 
    { 
     Entities.Refresh(RefreshMode.ClientWins, playerBuilding); 
     Entities.SaveChanges(); 
    } 
} 

を - あなたの方法は、静的あるので、多分それはですか?どのようにコンテキストをインスタンス化していますか?私はあなたがシングルトンを使用しないことを願っています。 :(

あり、あなたがそのエラーを取得理由をさらに詳細に説明し、どのような手順は、それに対抗するために行うことができますEFオプティミスティック同時here優れた記事は、コメントのRPMのためのおかげで

+0

。ですが、これは楽観的な並行性の問題ではありません。私はローカルの開発者のコ​​ンピュータで作業していますが、静的なメソッドを試していません。問題はありません。 -Entity-Framework-ObjectContext-lifespan-and-n-layered-ASP-NET-applications.aspx。何も変更しないでコンテキストをインスタンス化する通常の方法を使用して – Adir

+0

記事を見てください。その芸術家あなたとまったく同じです。単体テストで上記のコードを実行しようとしましたか?また、あなたが提供したその記事のどのような方法で文脈を具体化していますか? (その記事には複数のメソッドがあります) – RPM1984

+0

私はUnitOfWorkScopeメソッドを使用しましたが、問題はありません。古い方法(MyContext context = new MyContext())を使用してコンテキストをインスタンス化しても、同じエラーが表示され続けます。私はそれがコンテキストに存在しないオブジェクトを削除しようとしているので、それは並行性に関連しているとは思わない、エラーが表示されます。 – Adir

関連する問題