38

指定されたエンティティオブジェクトのproperty1とproperty2を除くすべてのフィールドを更新する必要があります。
このコードを持っている:

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

                context.SaveChanges();               
         }
        return View(obj);
    }

このコードで更新されないためにobj.property1とobj.property2に例外を追加するように変更するにはどうすればよいですか?

4

5 に答える 5

76

除外するプロパティのコレクションがあると仮定しましょう。

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

.NET 4.5のEF5を使用すると、次のことができます。

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

これは、.NET 4.5のEF5の新機能を使用しており、以前に変更に設定された後でも、プロパティを変更されないように設定できます。

.NET4でEF4.3.1またはEF5を使用する場合、代わりにこれを行うことができます。

var entry = context.Entry(obj);
foreach (var name in entry.CurrentValues.PropertyNames.Except(excluded))
{
    entry.Property(name).IsModified = true;
}
于 2012-04-22T20:38:28.253 に答える
22

このような例外を定義することはできません。ただし、単一のプロパティを変更済みとしてマークすることはできます。

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

エンティティ全体の状態をにマークすると、への設定はサポートされないIsModifiedことに注意してください。falseModified

あなたの目的のために、私は実際にデータベースからエンティティをロードし、通常の変更追跡を使用してそれを更新することを好みます:

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();
于 2012-04-21T12:06:22.760 に答える
12

この質問はすでにうまく答えられていますが、私はそれを使用したい人のために拡張メソッドを提供したいと思いました。

このコードはEF4.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();
}

使用例

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
}
于 2012-10-19T18:15:36.123 に答える
1

これは.netCOREで機能する更新であり、一般的な解決策が必要で、さまざまな条件に基づいて一部のプロパティを除外したい人に役立つ可能性があります。

私はリフレクションを使用してプロパティを反復処理し、そのプロパティ値に基づいて更新しています。この場合、例として、nullプロパティを除外しています。

    public virtual TEntity Update(TEntity entity)
    {
        dbSet.Attach(entity);
        dbContext.Entry(entity).State = EntityState.Modified;

        var entry = dbContext.Entry(entity);

        Type type = typeof(TEntity);
        PropertyInfo[] properties = type.GetProperties();
        foreach (PropertyInfo property in properties)
        {
            if (property.GetValue(entity, null) == null)
            {
                entry.Property(property.Name).IsModified = false;
            }
        }

        dbContext.SaveChanges();
        return entity;
    }
于 2020-04-20T07:11:35.820 に答える
0

上記の回答(ほとんど)はDbContextを使用しています。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");
于 2014-03-27T10:06:31.703 に答える