wake-up-neo.net

Eigenschaft beim Update in Entity Framework ausschließen

Ich habe nach einer geeigneten Methode gesucht, um eine Eigenschaft so zu markieren, dass sie beim Aktualisieren eines Modells in MVC NICHT geändert wird.

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 Editiermethode 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 jetzt das Token nicht enthält, wird sie durch diese Bearbeitung aufgehoben.

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 einzustellen.

59

wir können so verwenden

 db.Entry(model).State = EntityState.Modified;
 db.Entry(model).Property(x => x.Token).IsModified = false;
 db.SaveChanges();

es wird jedoch ohne Token-Eigenschaft aktualisiert

112
Nitin Dominic

Erstellen Sie ein neues Modell mit begrenzten Eigenschaften, die Sie aktualisieren möchten.

Das heißt 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 der Name geändert werden kann, das Kennzeichen Aktiviert jedoch nicht:

public class UserProfileModel
{
   public int Id {get;set;}
   public string Name {get;set;}
}

Wenn Sie eine Datenbankaktualisierung durchführen möchten, führen Sie folgende Schritte aus:

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 bekommen ein Bild davon, wie man es benutzt.

6
Admir Tuzović

Ich vermute, Sie möchten nicht, dass die Eigenschaft in einigen Fällen geändert wird. Wenn Sie sie nicht verwenden, entfernen Sie sie einfach aus Ihrem Modell.

Wenn Sie es nur in einigen Szenarien verwenden möchten und im obigen Fall dessen "Aufhebung" vermeiden möchten, können Sie versuchen:

  • Verstecke den Parameter in der Ansicht mit HiddenFor:

    @Html.HiddenFor(m => m.Token)

Dadurch bleibt Ihr ursprünglicher Wert unverändert und wird an die Steuerung zurückgegeben.

Laden Sie Ihr Objekt erneut aus Ihrem DBSet in den Controller und führen Sie diese Methode aus. Sie können sowohl eine Whitelist als auch eine Blacklist von Parametern angeben, die aktualisiert werden sollen oder nicht.

1
Jaime

Ich habe eine einfache Methode zum Bearbeiten von Eigenschaften von Entitäten erstellt, die ich mit Ihnen teilen werde.

    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 Name und Family 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
}
0
Ali Yousefie