Entity Framework 5 を使用する MVC アプリケーションがあります。いくつかの場所で、エンティティを作成または更新し、更新されたデータに対して何らかの操作を実行する必要があるコードがあります。これらの操作の一部では、ナビゲーション プロパティにアクセスする必要があり、それらを更新できません。
これが例です(私が持っている簡略化されたコード)
モデル
class User : Model
{
public Guid Id { get; set; }
public string Name { get; set; }
}
class Car : Model
{
public Guid Id { get; set; }
public Guid DriverId { get; set; }
public virtual User Driver { get; set; }
[NotMapped]
public string DriverName
{
get { return this.Driver.Name; }
}
}
コントローラ
public CarController
{
public Create()
{
return this.View();
}
[HttpPost]
public Create(Car car)
{
if (this.ModelState.IsValid)
{
this.Context.Cars.Create(booking);
this.Context.SaveChanges();
// here I need to access some of the resolved nav properties
var test = booking.DriverName;
}
// error handling (I'm removing it in the example as it's not important)
}
}
上記の例は Create メソッドのものですが、Update メソッドにも同じ問題があります。これは非常によく似ており、動作中のコンテキストからオブジェクトを取得し、動作中のメソッドをGET
使用してそれを格納するだけです。Update
POST
public virtual void Create(TObject obj)
{
return this.DbSet.Add(obj);
}
public virtual void Update(TObject obj)
{
var currentEntry = this.DbSet.Find(obj.Id);
this.Context.Entry(currentEntry).CurrentValues.SetValues(obj);
currentEntry.LastModifiedDate = DateTime.Now;
}
今、グーグルで検索したりスタックで見つけたりしたいくつかの異なるアプローチを試しましたが、何もうまくいかないようです。
私の最近の試みでは、SaveChanges
メソッドを呼び出してデータベースからデータを再クエリした後、リロードを強制しようとしました。これが私がやったことです。
SaveChanges
保存直後にオブジェクト コンテキストを更新するメソッドを上書きしました
public int SaveChanges()
{
var rowsNumber = this.Context.SaveChanges();
var objectContext = ((IObjectContextAdapter)this.Context).ObjectContext;
objectContext.Refresh(RefreshMode.StoreWins, this.Context.Bookings);
return rowsNumber;
}
アクションSaveChanges
の呼び出しHTTP
Create
の直後に次のコード行を追加して、更新されたオブジェクト データを取得しようとしました。Update
car = this.Context.Cars.Find(car.Id);
残念ながら、ナビゲーション プロパティはまだnull
. データを変更した直後に DbContext を適切に更新するにはどうすればよいですか?
編集
回避策を知っていることを最初に言うのを忘れていましたが、それは醜く、好きではありません。ナビゲーション プロパティを使用するときはいつでもnull
、新しい DbContext を手動で作成してデータを更新できるかどうかを確認できます。しかし、このようなハッキングは避けたいと思います。
class Car : Model
{
[NotMapped]
public string DriverName
{
get
{
if (this.Driver == null)
{
using (var context = new DbContext())
{
this.Driver = this.context.Users.Find(this.DriverId);
}
}
return this.Driver.Name;
}
}
}