2016-04-26 5 views
0

新しいFOREIGN KEY値を設定した後でエンティティを更新しようとします。DBContextを使った明示的ロードが機能しない/値が変更されない

マイ(簡体字)の実体は、以下のとおりです。私のコードの中でいくつかの点で

public class FirstEntity 
{ 
    public Guid Id { get; set; } 
    public Guid SecondEntityId {get; set;} // <-- this is the FK   
    public virtual SecondEntity SecondEntity { get; set; } // <-- this is the navigation property 
} 

public class SecondEntity 
{ 
    public Guid Id { get; set;}  
    public virtual ICollection<FirstEntity> FirstEntity { get; set; } 
} 

は、私が新しい値にFK-値を設定することにより、タイプFirstEntityのオブジェクトの参照を変更したいです。

var theFirstEntity = DbContext.FirstEntity.Single(f => f.Id == Guid.Parse("5e27bfd3-d65b-4164-a0e4-93623e1b0de0")); 
// at this point theFirstEntity.SecondEntityId is 'e06f8909-98f9-4dc6-92ec-49d9a6aac831' 

theFirstEntity.SecondEntityId = Guid.Parse("C5AB5CBA-5CD8-40B7-ABFB-C22F17646D44"); // <-- existing Id from database 
// now theFirstEntity.SecondEntityId is 'C5AB5CBA-5CD8-40B7-ABFB-C22F17646D44' 
// but the reference theFirstEntity.SecondEntity is still pointing the 'old' entity with id 'e06f8909-98f9-4dc6-92ec-49d9a6aac831' 
// but it should have id 'C5AB5CBA-5CD8-40B7-ABFB-C22F17646D44 

今私はhereが見つかったとして明示的に

DbContext.Entry(FirstEntity).Reference(t => t.SecondEntity).Load(); 

を使用して新しい参照をロードしよう。

しかし、FirstEntity.SecondEntityはこれまでと同じSystem.Data.Entity.DynamicProxies.SecondEntity_XYZのままです。 もう一方で、DbContext.Entry(FirstEntity).Reference(t => t.SecondEntity).Query()Parametersプロパティの値を見ると、Id = 'C5AB5CBA-5CD8-40B7-ABFB-C22F17646D44'を調べることによってクエリが正しいように見えます。

代わりに、Id 'C5AB5CBA-5CD8-40B7-ABFB-C22F17646D44'の 'SecondEntity'タイプの正しいエンティティが含まれていて、 '古い'値ではありません。

+0

質問? ")には、目的の振る舞い、特定の問題またはエラー、および質問自体にそれを再現するのに必要な最短コードが含まれていなければなりません。明確な問題文がない質問は、他の読者にとって有用ではありません。参照:最小、完全、および検証可能な例を作成する方法。 – TomTom

+0

必要な動作は、正しいプロパティ値を設定することです。問題は、プロパティを明示的に読み込んだ後もそのままであることです。再現するコードが追加されました。これは大丈夫ですか? – KingKerosin

+0

@KingKerosin、申し訳ありませんがあなたの主な問題については分かりませんが、とにかくGuidをプライマリキー(実際にはクラスタ化インデックス)として使用しないでください。これはSQL Serverを使用する悪い方法です。 http://stackoverflow.com/questions/11938044/what-are-the-best-practices-for-using-a-guid-as-a-primary-key-specifically-rega – Thomas

答えて

0

変更を保存して明示的に読み込む必要があります。

theFirstEntity = myDbContext.FirstEntity.Single(f => f.Id == Guid.Parse("5e27bfd3-d65b-4164-a0e4-93623e1b0de0")); 
theFirstEntity.SecondEntityId = Guid.Parse("C5AB5CBA-5CD8-40B7-ABFB-C22F17646D44"); 

myDbContext.SaveChanges(); 

DbContext.Entry(theFirstEntity).Reference(t => t.SecondEntity).Load(); 

しかし、この場合には、それは単に新しいとすでにFirstEntitySecondEntity値をロードを割り当てることがより便利になります:デバッグのヘルプ(「なぜこのコードは動作していないを求めて

var f = myDbContext.Set<FirstEntity>().Include(p => p.SecondEntity) 
    .Single(x => x.Id == Guid.Parse("5e27bfd3-d65b-4164-a0e4-93623e1b0de0")); 

var s = myDbContext.Set<SecondEntity>() 
    .Single(x => x.Id == Guid.Parse("C5AB5CBA-5CD8-40B7-ABFB-C22F17646D44")); 

f.SecondEntity = s; 

myDbContext.SaveChanges(); 
+0

例/質問はほんの一例であるため、私の実際のアプリケーションでは、それはさらに大きなフレームワークの中にあります。したがって、 'SaveChanges()'は常に基底のデータベースにヒットします。 私が欲しいものを達成する他の方法はないと思いますか? EntityStatesなどで遊んでいますか? – KingKerosin

+0

実際の関連エンティティが何か他のものであるとEFが信じるようにしたいのであれば、それはデータベースにあり、それをEFオブジェクトグラフにロードすることは良い考えではありません。 ViewModel、カスタムクラスなどのように、自分自身で別のオブジェクトグラフを作成してください。 –

+0

変更された後で参照を読み込む際に、「不正行為」のように感じられませんか?おそらく、コンテキストやエンティティを変更後にリフレッシュするという全く別の方法がありますか? – KingKerosin

関連する問題