Ich habe nach einer geeigneten Möglichkeit gesucht, eine Eigenschaft zu markieren, die beim Aktualisieren eines Modells in MVC NICHT geändert werden soll.
Nehmen wir zum Beispiel dieses kleine Modell:
class Model
{
[Key]
public Guid Id {get; set;}
public Guid Token {get; set;}
//... lots of properties here ...
}
Dann sieht die von MVC erstellte Bearbeitungsmethode folgendermaßen aus:
[HttpPost]
public ActionResult Edit(Model model)
{
if (ModelState.IsValid)
{
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(model);
}
Wenn meine Ansicht das Token nicht enthält, wird es durch diese Bearbeitung ungültig.
Ich suche so etwas:
db.Entry(model).State = EntityState.Modified;
db.Entry(model).Property(x => x.Token).State = PropertyState.Unmodified;
db.SaveChanges();
Der beste Weg, den ich bisher gefunden habe, ist, inklusiv zu sein und alle Eigenschaften, die ich einschließen möchte, von Hand festzulegen, aber ich möchte wirklich nur sagen, welche ausgeschlossen werden sollen.
c#
asp.net-mvc
entity-framework
Manuel Schweigert
quelle
quelle
using (var db2 = new DataContext()) model.Token = db2.Models.Find(model.Id).Token;
Aber ich bin auch mit dieser nicht zufrieden.Antworten:
wir können so verwenden
db.Entry(model).State = EntityState.Modified; db.Entry(model).Property(x => x.Token).IsModified = false; db.SaveChanges();
Es wird aktualisiert, jedoch ohne Token-Eigenschaft
quelle
AddOrUpdate
? - Woher weißt du,EntityState.Modified
oderEntityState.Added
?db.Entry(model).State = EntityState.Modified;
nach der Einstellung festlegendb.Entry(model).Property(x => x.Token).IsModified = false;
, wird die Eigenschaft beim Speichern aktualisiert.Erstellen Sie ein neues Modell mit begrenzten Eigenschaften, die Sie aktualisieren möchten.
Dh wenn Ihr Entitätsmodell ist:
public class User { public int Id {get;set;} public string Name {get;set;} public bool Enabled {get;set;} }
Sie können ein benutzerdefiniertes Ansichtsmodell erstellen, mit dem Benutzer den Namen ändern können, jedoch nicht das Flag Aktiviert:
public class UserProfileModel { public int Id {get;set;} public string Name {get;set;} }
Wenn Sie eine Datenbankaktualisierung durchführen möchten, gehen Sie wie folgt vor:
YourUpdateMethod(UserProfileModel model) { using(YourContext ctx = new YourContext()) { User user = new User { Id = model.Id } ; /// stub model, only has Id ctx.Users.Attach(user); /// track your stub model ctx.Entry(user).CurrentValues.SetValues(model); /// reflection ctx.SaveChanges(); } }
Wenn Sie diese Methode aufrufen, aktualisieren Sie den Namen, die Enabled-Eigenschaft bleibt jedoch unverändert. Ich habe einfache Modelle verwendet, aber ich denke, Sie werden sich ein Bild davon machen, wie man es benutzt.
quelle
Jeder, der danach sucht, wie dies auf EF Core erreicht werden kann. Es ist im Grunde das gleiche, aber Ihr IsModified muss sein, nachdem Sie das zu aktualisierende Modell hinzugefügt haben.
db.Update(model); db.Entry(model).Property(x => x.Token).IsModified = false; db.SaveChanges();
quelle
Ich habe eine einfache Möglichkeit zum Bearbeiten von Eigenschaften von Entitäten erstellt, die ich mit Ihnen teilen werde. Dieser Code bearbeitet die Eigenschaften Name und Familie der Entität:
public void EditProfileInfo(ProfileInfo profileInfo) { using (var context = new TestContext()) { context.EditEntity(profileInfo, TypeOfEditEntityProperty.Take, nameof(profileInfo.Name), nameof(profileInfo.Family)); } }
Dieser Code wird ignoriert, um die Eigenschaften von Name und Familie der Entität zu bearbeiten, und es werden andere Eigenschaften bearbeitet:
public void EditProfileInfo(ProfileInfo profileInfo) { using (var context = new TestContext()) { context.EditEntity(profileInfo, TypeOfEditEntityProperty.Ignore, nameof(profileInfo.Name), nameof(profileInfo.Family)); } }
Verwenden Sie diese Erweiterung:
public static void EditEntity<TEntity>(this DbContext context, TEntity entity, TypeOfEditEntityProperty typeOfEditEntityProperty, params string[] properties) where TEntity : class { var find = context.Set<TEntity>().Find(entity.GetType().GetProperty("Id").GetValue(entity, null)); if (find == null) throw new Exception("id not found in database"); if (typeOfEditEntityProperty == TypeOfEditEntityProperty.Ignore) { foreach (var item in entity.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty)) { if (!item.CanRead || !item.CanWrite) continue; if (properties.Contains(item.Name)) continue; item.SetValue(find, item.GetValue(entity, null), null); } } else if (typeOfEditEntityProperty == TypeOfEditEntityProperty.Take) { foreach (var item in entity.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty)) { if (!item.CanRead || !item.CanWrite) continue; if (!properties.Contains(item.Name)) continue; item.SetValue(find, item.GetValue(entity, null), null); } } else { foreach (var item in entity.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty)) { if (!item.CanRead || !item.CanWrite) continue; item.SetValue(find, item.GetValue(entity, null), null); } } context.SaveChanges(); } public enum TypeOfEditEntityProperty { Ignore, Take }
quelle
Ich denke, Sie möchten nicht, dass die Eigenschaft nur in einigen Fällen geändert wird. Wenn Sie sie nicht in Ihrer Anwendung verwenden möchten, entfernen Sie sie einfach aus Ihrem Modell.
Wenn Sie es nur in einigen Szenarien verwenden und seine "Aufhebung" im obigen Fall vermeiden möchten, können Sie Folgendes versuchen:
Blenden Sie den Parameter in der Ansicht mit HiddenFor aus:
@Html.HiddenFor(m => m.Token)
Dadurch bleibt Ihr ursprünglicher Wert unverändert und wird an die Steuerung zurückgegeben.
TryUpdateModel
: http://msdn.microsoft.com/en-us/library/dd460189(v=vs.108).aspxLaden Sie Ihr Objekt erneut von Ihrem in den Controller
DBSet
und führen Sie diese Methode aus. Sie können sowohl eine weiße Liste als auch eine schwarze Liste von Parametern angeben, die aktualisiert werden sollen oder nicht.quelle
@Html.HiddenFor
wird der Wert in den HTML-Code der Ansicht geschrieben und der Benutzer kann das Inspect-Element in seinem Browser verwenden und ändern. Danach wird es weiterhin an den Controller übergeben, jedoch mit einem anderen Wert, und aktualisiert. Ich habe es gerade getestet.