Вопрос по entity-framework, entity-framework-4.1 – Как обновить не все поля объекта, используя Entity Framework и EntityState.Modified

32

Мне нужно обновить все поля, кроме property1 и property2 для данного объекта сущности.
Имея этот код:

<code>    [HttpPost]
    public ActionResult Add(object obj)
    {
        if (ModelState.IsValid)
        {
                context.Entry(obj).State = System.Data.EntityState.Modified;

                context.SaveChanges();               
         }
        return View(obj);
    }
</code>

Как изменить это, чтобы добавить исключение в obj.property1 и obj.property2 для того, чтобы не обновляться с этим кодом?

Ваш Ответ

4   ответа
19

дельные свойства как измененные:

context.Entry(obj).Property(o => o.Property3).IsModified = true;
context.Entry(obj).Property(o => o.Property4).IsModified = true;
// etc.

Обратите внимание, что настройкаIsModified вfalse не поддерживается, если вы отметили состояние всей сущности дляModified.

Для вашей цели я бы предпочел загрузить объект из базы данных, а затем обновить его, используя обычное отслеживание изменений:

var objInDB = context.Objects.Single(o => o.Id == obj.Id);

obj.Property1 = objInDB.Property1;
obj.Property2 = objInDB.Property2;

context.Entry(objInDB).CurrentValues.SetValues(obj);

context.SaveChanges();
Мне нравится ваш второй блок кода, который является хорошим обратным решением не использовать ложное утверждение. mhmd
Я заметил похожую заметку здесь:msdn.microsoft.com/en-us/library/jj592677(v=vs.113).aspx что говорит "В настоящее время невозможно сбросить отдельное свойство, которое не было изменено, после того, как оно было помечено как измененное. Это то, что мы планируем поддержать в следующем выпуске. & Quot; Однако это сработало, когда я попробовал. Возможно, эта страница MSDN устарела, хотя там говорится, что она была обновлена 23 октября 2016 года.
+1 для следующего: & quot; Обратите внимание, что установка IsModified в значение false не поддерживается, если вы пометили состояние всей сущности как измененное. & Quot;
9

но я хотел предоставить метод расширения для всех, кто хотел бы его использовать.

Этот код был разработан для EF 4.3.1

//You will need to import/use these namespaces    
using System.Data.Entity;
using System.Data.Entity.Infrastructure;    

//Update an entity object's specified columns, comma separated
//This method assumes you already have a context open/initialized
public static void Update<T>(this DbContext context, T entityObject, params string[] properties) where T : class
{
    context.Set<T>().Attach(entityObject);

    var entry = context.Entry(entityObject);

    foreach(string name in properties)
        entry.Property(name).IsModified = true;

    context.SaveChanges();
}

Usage Example

using (FooEntities context = new FooEntities())
{
    FooEntity ef = new FooEntity();

    //For argument's sake say this entity has 4 columns: 
    //    FooID (PK), BarID (FK), Name, Age, CreatedBy, CreatedOn

    //Mock changes
    ef.FooID = 1;
    ef.Name = "Billy";
    ef.Age = 85;

    context.Update<FooEntity>(ef, "Name", "Age"); //I only want to update Name and Age
}
63

var excluded = new[] { "property1", "property2" };

С EF5 на .NET 4.5 вы можете сделать это:

var entry = context.Entry(obj);
entry.State = EntityState.Modified;
foreach (var name in excluded)
{
    entry.Property(name).IsModified = false;
}

При этом используется новая функция EF5 в .NET 4.5, которая позволяет задавать свойство как неизмененное даже после того, как оно было ранее изменено.

При использовании EF 4.3.1 или EF5 в .NET 4 вы можете сделать следующее:

var entry = context.Entry(obj);
foreach (var name in entry.CurrentValues.PropertyNames.Except(excluded))
{
    entry.Property(name).IsModified = true;
}
@Arthur - должен ли он работать как & quot; entry.Property (obj.name) .IsModified = false & quot ;?
Приятное улучшение в .NET 4.5, спасибо!
Какое замечательное решение для .NET 4.5, я использовал его в реализации IUnitOfWork + DI, и это действительно впечатляет, спасибо!
Да уж. Это отличная реализация этого в .Net 4.5 mhmd
Я знаю, что это подразумевается, но я просто хотел явно заявить, что для EF 4.3.1 - вы не можете установить entry.Property (...). IsModified = false; - он скомпилируется, но при попытке сделать это вы получите ошибку во время выполнения. Поэтому я думаю, что есть смысл сказать, что для EF 4.3.1 вы должны использовать только положительные стороны, другими словами: вы можете помечать вещи как измененные (true), поскольку они уже установлены как неизмененные (false). EF 5 позволяет вам свободно устанавливать true / false;
0

кто использует ObjectContext, эти решения недоступны.

Вот решение дляObjectContext строго (EF5 .NET 4.5):

ctx.AddObject("ENTITYNAME", item);
ctx.ObjectStateManager.ChangeObjectState(item, EntityState.Modified);

var entry = ctx.ObjectStateManager.GetObjectStateEntry(item);
entry.RejectPropertyChanges("PROPERTY_TO_EXCLUDE");

Похожие вопросы