Mam aplikację MVC, która korzysta z Entity Framework 5. W kilku miejscach mam kod, który tworzy lub aktualizuje podmioty, a następnie musi wykonać jakieś operacje na zaktualizowanych danych . Niektóre z tych operacji wymagają dostępu do właściwości nawigacji i nie mogę ich odświeżyć.Entity Framework 5 - Natychmiast odśwież DbContext po zapisaniu zmian
Oto przykład (uproszczony kod, który mam)
modele
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; }
}
}
Controller
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)
}
}
Powyższy przykład jest dla metody Create, ale ja też mam ten sam problem z metodą aktualizacji, która jest bardzo podobna, po prostu bierze obiekt z kontekstu w akcji GET
i przechowuje go przy użyciu metody Update
w akcji.
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;
}
Teraz próbowałem kilka różnych podejść, że google lub znalezione na stosie, ale nic nie wydaje się działać dla mnie.
W mojej ostatniej próbie spróbowałem wymusić przeładowanie po wywołaniu metody SaveChanges
i przesłaniu danych z bazy danych. Oto co zrobiłem.
mam ovewrite metody SaveChanges
odświeżyć kontekst obiektu natychmiast po zapisać
public int SaveChanges()
{
var rowsNumber = this.Context.SaveChanges();
var objectContext = ((IObjectContextAdapter)this.Context).ObjectContext;
objectContext.Refresh(RefreshMode.StoreWins, this.Context.Bookings);
return rowsNumber;
}
Próbowałem uzyskanie zaktualizowanych danych obiektu przez dodanie tej linii kodu natychmiast po SaveChanges
rozmowy w moim HTTP
Create
i Update
Działania:
car = this.Context.Cars.Find(car.Id);
Niestety, właściwość nawigacji nadal jest null
. Jak mogę poprawnie odświeżyć DbContext natychmiast po modyfikacji danych?
EDIT
zapomniałem wspomnieć, że pierwotnie wiem obejście, ale jest brzydki i nie podoba. Ilekroć używam właściwości nawigacji, mogę sprawdzić, czy jest to null
, a jeśli tak, mogę ręcznie utworzyć nowy DbContext i zaktualizować dane. Ale naprawdę chciałbym uniknąć takich hacków.
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;
}
}
}
Co o moim 'metody Update'? Czy powinienem również pobrać oryginalny obiekt inny niż 'this.Context.Cars.Find (id)'? – RaYell
'Znajdź' zwróci obiekt proxy z bazy danych, ale jeśli znajdujesz i aktualizujesz obiekt, który został dodany lokalnie podczas tej transakcji, to znajdzie dodany obiekt. – qujck
Próbowałem podążać za rozwiązaniem, ale to doprowadziło mnie do "System.InvalidOperationException: Member" CurrentValues "nie można wywołać dla encji typu" Car ", ponieważ podmiot nie istnieje w kontekście. Aby dodać obiekt do kontekstu, należy wywołać metodę Add lub Attach z DbSet. "Dodałem' this.Context.Set () .Attach (newEntry); 'zaraz po twojej pierwszej linii i teraz otrzymuję' System.InvalidOperationException: Właściwość "Id" jest częścią kluczowych informacji obiektu i nie można jej modyfikować. " –
RaYell