4

我正在使用 ASP.NET MVC4 Web API 和我的 PUT 操作,我想做这样的事情:

public void Put(string id, [FromBody]Foo value)
{
    var context = new FooBarEntities();
    Foo existingFoo = context.Foos.Where(x => x.Id == id).First();
    existingFoo = value;
    context.SaveChanges();
}

Foo value但不会保存对象中的更改。如果我要执行每个属性,它会起作用,如下所示:

public void Put(string id, [FromBody]Foo value)
{
    var context = new FooBarEntities();
    Foo existingFoo = context.Foos.Where(x => x.Id == id).First();
    existingFoo.Prop1 = value.Prop1;
    existingFoo.Prop2 = value.Prop2;
    context.SaveChanges();
}

有没有一种方法可以通过分配对象来更新每个属性?

4

4 回答 4

2

这绝对行不通:

Foo existingFoo = context.Foos.Where(x => x.Id == id).First();
existingFoo = value;

您正在查找它,然后立即用完全不同的东西覆盖引用。

我想你想要attachvalue的上下文然后做一个保存。更像这样的东西可能会为你做:

context.Foos.AddObject(value);
context.ObjectStateManager.ChangeObjectState(value, System.Data.EntityState.Modified);
context.SaveChanges();

这不需要您首先加载要更新的对象,这很好。如果那不这样做,那么知道这被称为disconnected更新可能会帮助您未来的谷歌搜索。

如果您已经拥有要更新的对象以及新副本,我不知道有什么干净的东西可以为您合并它们。


我以前做过的另一种方式看起来更像这样,这可能感觉不那么老套:

var entity = context.Entry(value);
entity.State = EntityState.Modified;
context.SaveChanges();

或更简洁地说:

context.Entry(value).State = EntityState.Modified;
context.SaveChanges();

不过,我不记得这是不是内置的东西。

于 2013-04-19T14:42:48.107 回答
1

简短的回答:没有。

但是有很多方法可以获得相同的结果,我曾经编写过这段代码,它使用反射来复制对象的所有属性:

    public void CopyLinqObject(object obj_source, object obj_dest)
    {
        Type t_source = obj_source.GetType();
        PropertyInfo[] p_source = t_source.GetProperties();

        Type t_dest = obj_dest.GetType();
        PropertyInfo[] p_dest = t_dest.GetProperties();

        foreach (PropertyInfo ps in p_source)
        {
            foreach (PropertyInfo pd in p_dest)
            {
                if (ps.Name == pd.Name)
                {
                    if (ps.PropertyType == pd.PropertyType)
                    {
                        if (ps.PropertyType.IsSerializable)
                        {
                            pd.SetValue(obj_dest, ps.GetValue(obj_source, null), null);
                        }
                    }
                    else
                    {
                        if (ps.PropertyType.BaseType == pd.PropertyType.BaseType)
                        {
                            if (ps.PropertyType.IsSerializable)
                            {
                                if (ps.GetValue(obj_source, null) != null)
                                {
                                    try
                                    {
                                        pd.SetValue(obj_dest, ps.GetValue(obj_source, null), null);
                                    }
                                    catch
                                    {
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
于 2013-04-19T14:43:49.483 回答
0

有没有一种方法可以通过分配对象来更新每个属性?

,EF 跟踪属性的变化,它们的类实现了inotifypropertychanged,当您只是更改变量引用时,您没有更改属性。

于 2013-04-19T14:43:52.313 回答
0

您不能以这种方式将一个对象的属性“分配”给另一个对象。您的代码只是更改变量existingFoo 的值。

您可以实现自己的属性复制代码,也可以查看将类附加到现有数据上下文。

于 2013-04-19T14:42:42.357 回答