2013-04-19 2 views
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(); 
} 

Есть ли способ, что я могу обновляться каждое свойство, только назначая объект?

+0

Возможный дубликат [Что эквивалентно ObjectContext.ApplyCurrentValues ​​для DbContext] (http://stackoverflow.com/questions/5807622/what-is-the-equivalent-of-objectcontext-applycurrentvalues-for-dbcontext). Отмечено как дубликат, потому что он содержит ответ на ваш вопрос, но я могу представить, что вы не знали об этом. Не волнуйтесь, дубликаты не являются преступлением. –

+0

@ GertArnold может быть. Я думаю [этот вопрос/ответ] (http://stackoverflow.com/questions/623672/update-entity-framework-objects/4212581#4212581), что Майкл Харен, связанный ниже, является более близким дубликатом, с ответом. – xdumaine

+0

Не связано с вашим вопросом: '.Where (x => ...). First()' обычно можно заменить на '.First (x => ...)'. Если должен быть только один, тогда '.Single (x => ...)' будет еще лучше. Если должно быть 0 или 1, я бы использовал 'SingleOrDefault (x => ...)' и проверить значение null. –

ответ

2

Это, безусловно, не будет работать:

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

Вы смотрите его, а затем сразу же перезаписать ссылку с чем-то совершенно другим.

Я думаю, вы хотите, чтобы attach ваш value в контекст, а затем сделать сэкономь. Что-то более like this может сделать это для вас:

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

Это не требует, чтобы вы загружаете объект, который будет обновлен первый, что приятно. Если это не так, то зная, что это называется чем-то вроде disconnected, обновление может помочь вашему будущему поиску в Google.

Если у вас уже есть объект, который будет обновляться в руке, вместе с новой копией, я не знаю ничего чистого, чтобы слить их для вас.


Другой способ I've done it прежде, чем выглядит больше как это, что может чувствовать себя менее Hacky:

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

Или более кратко:

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

Я не могу вспомнить, если это встроенный вещь или нет.

+0

Просто протестировал это и, похоже, сделал именно то, что искал. Это кажется немного взломанным, как будто это * tricking * entity framework. – xdumaine

+0

Сначала это может быть странно, но я не думаю, что это взломать. Вы тоже можете использовать этот подход для удаления. –

0

Вы не можете «назначить» свойства одного объекта другому. Ваш код просто меняет значение переменной existingFoo.

Вы можете либо реализовать свой собственный код копирования свойств, либо взглянуть на присоединение класса к существующему контексту данных.

1

Короткий ответ: Нет

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

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 
            { 
            } 
           } 
          } 
         } 
        } 
       } 
      } 
     } 
    } 
0

Is есть способ, которым я могу обновить каждое свойство, просто назначив объект?

Нет, отслеживать изменения EF со свойствами, они не классы реализации inotifypropertychanged, когда вы просто изменить ссылку на переменную, вы не изменили свойства.

+1

Я предполагаю, что имел в виду «назначая объект * или что-то подобное простое, и если да, то как?» – xdumaine

Смежные вопросы