Nach meiner anderen Frage zum Verspotten von DbContext.Set habe ich noch eine Frage zum Verspotten von EF Code First.
Ich habe jetzt eine Methode für mein Update, die so aussieht:
if (entity == null)
throw new ArgumentNullException("entity");
Context.GetIDbSet<T>().Attach(entity);
Context.Entry(entity).State = EntityState.Modified;
Context.CommitChanges();
return entity;
Context ist eine Schnittstelle meines eigenen DbContext.
Das Problem, auf das ich stoße, ist, wie ich mit dem umgehen soll
Context.Entry(entity).State
.
Ich habe diesen Code schrittweise durchgearbeitet und er funktioniert, wenn ich einen echten DbContext als Implementierung meiner Context-Schnittstelle habe. Aber wenn ich meinen falschen Kontext dort platziere, weiß ich nicht, wie ich damit umgehen soll.
Es gibt keinen Konstruktor für eine DbEntityEntry-Klasse, daher kann ich in meinem falschen Kontext nicht einfach einen neuen erstellen.
Hat jemand Erfolg damit gehabt, DbEntityEntry in Ihren CodeFirst-Lösungen zu verspotten oder zu fälschen?
Oder gibt es eine bessere Möglichkeit, mit den Zustandsänderungen umzugehen?
Genau wie im anderen Fall müssen Sie eine zusätzliche Ebene der Indirektion hinzufügen:
interface ISalesContext
{
IDbSet<T> GetIDbSet<T>();
void SetModified(object entity)
}
class SalesContext : DbContext, ISalesContext
{
public IDbSet<T> GetIDbSet<T>()
{
return Set<T>();
}
public void SetModified(object entity)
{
Entry(entity).State = EntityState.Modified;
}
}
Statt die Implementierung aufzurufen, rufen Sie einfach SetModified
auf.
Ich habe diese Frage gefunden, als ich mit Moq
einen Unit-Test durchführen musste, keine eigene Schnittstelle. Ich wollte bestimmte Felder so einstellen, dass sie nicht geändert wurden, aber die Methode SetModified
kann auch mit dem Objekt verwendet werden.
DbContext:
public class AppDbContext : DbContext
{
...
public virtual void SetModified(GuidEntityBase entity)
{
Entry(entity).State = EntityState.Modified;
Entry(entity).Property(x => x.CreatedDate).IsModified = false;
Entry(entity).Property(x => x.CreatedBy).IsModified = false;
}
...
}
Prüfung:
var mockContext = new Mock<AppDbContext>();
mockContext.Setup(c => c.MyDbSet).Returns(mockMyDbSet.Object);
mockContext.Setup(c => c.SetModified(It.IsAny<GuidEntityBase>()));