2014-02-10 4 views
2

У меня есть объект таблицы STUDENT, в котором у меня есть новые значения, и я хочу обновить таблицу STUDENT этими новыми значениями. мой код приведен ниже (который работает для копирования свойств из STD в getdata, но), не обновляя значения в таблице STUDENT в базе данных, почему? заранее спасибо.Как скопировать все свойства объекта в другой в LINQ

public void UpdateStudent(STUDENT STD) 
    { 
     context = new ERPDataContext(); 
     var getdata = context.STUDENTs.SingleOrDefault(obj=>obj.ID==STD.ID); 
     getdata = STD; 
     context.SubmitChanges(); 
    } 
+2

При использовании ссылочных типов (в C#, что это почти все, кроме вашего основного 'int',' bool' и т.д.), назначая один ссылочный тип к другому будет эффективно бросить от старых значений. В вашем случае вы получаете ученика, затем бросаете его и заменяете его тем, который у вас есть, который не привязан к контексту, который вы передаете 'SubmitChanges()'. –

ответ

4

Вы можете использовать отражение здесь. Не очень уверен, решит ли он вашу проблему полностью. Также использование отражения может быть излишним, поэтому, пожалуйста, проверьте производительность.

Я использовал фиктивный класс «А», чтобы объяснить, как вы можете его использовать. Проверьте это и дайте мне знать, если это сработает.

public class A 
    { 
     public string aField { get; set; } 
    } 

И код:

 A obj1 = new A(); 
     A obj2 = new A(); 

     obj1.aField = "aaa"; 

     var propInfo = obj1.GetType().GetProperties(); 
     foreach (var item in propInfo) 
     { 
      obj2.GetType().GetProperty(item.Name).SetValue(obj2, item.GetValue(obj1, null), null); 
     } 

Конечно, вы должны добавить пространство имен:

using System.Reflection; 

Надеется, что это помогает.

+0

Thankyou Это сработало для меня –

3

Вы должны обновить все свойства вручную:

var getdata = context.STUDENTs.SingleOrDefault(obj=>obj.ID==STD.ID); 
getdata.Prop1 = STD.Prop1; 
getdata.Prop2 = STD.Prop2; 
context.SubmitChanges(); 

В противном случае, вы просто заменить getdata ссылку, а не изменить сам объект.

Или вы можете использовать следующие:

var getdata = context.STUDENTs.SingleOrDefault(obj=>obj.ID==STD.ID); 
var entry = context.Entry(getdata); 
entry.CurrentValues.SetValues(STD); 
entry.State = EntityState.Modified; 
context.SubmitChanges(); 
+0

Имеет ли строка 'entry.CurrentValues.SetValues ​​(STD);' копирует все свойства 'STD' и устанавливает его в' getdata'? –

+1

@nowhewhustwithbename Да, вот как это работает. – MarcinJuraszek

+0

Что такое Entry(), что любая предопределенная функция C# или что-то еще? –

1

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

context.STUDENTs.Attach(STD); 
var entry = context.Entry(STD); 
context.SubmitChanges(); 

Также вы можете обновить свойства которого изменились:

var getdata = context.STUDENTs.SingleOrDefault(obj=>obj.ID==STD.ID); 
getdata.Property = STD.Property; 
context.SubmitChanges(); 
+0

Что такое "db.Entry()"? что любая предопределенная функция или somthing? –

+0

Я изменил его на context.Entry(). –

+0

Но в этом проекте я не вижу. В моем проекте intellisense (и он не будет предлагать ссылку на пространство имен, если я просто ввожу его) –

1

Ниже представлен вариант ответа @ samar, но внутренний раздел завернут if, который проверяет свойство CanWrite, в противном случае вы получите сообщение об ошибке.

 A obj1 = new A(); 
    A obj2 = new A(); 

    obj1.aField = "aaa"; 

    var propInfo = obj1.GetType().GetProperties(); 
    foreach (var item in propInfo) 
    { 
     if(item.CanWrite) 
     { 
      obj2.GetType().GetProperty(item.Name).SetValue(obj2, item.GetValue(obj1, null), null); 
     } 
    } 

Обновлен с очень родовой вспомогательной функцией:

 protected void CopyEntityObject<T>(ref T old, ref T updated) 
    { 
     var propInfo = old.GetType().GetProperties(); 
     foreach (var item in propInfo) 
     { 
      if (item.CanWrite) 
      { 
       old.GetType().GetProperty(item.Name).SetValue(old, item.GetValue(updated, null), null); 
      } 
     } 
    } 
+0

Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий ниже своего сообщения - вы всегда можете прокомментировать свои собственные сообщения, и как только у вас будет достаточно [репутации] (http://stackoverflow.com/help/whats-reputation), вы будете быть в состоянии [прокомментировать любое сообщение] (http://stackoverflow.com/help/privileges/comment). – SBirthare

+0

Sbirthare, вы должны иметь 50 представителей, чтобы прокомментировать какой-то ответ. У меня не было другого способа добавить мою информацию, кроме как добавить мой собственный ответ. Таким образом, я не мог критиковать или запрашивать разъяснения непосредственно на samar, как указано в моем ответе. –

+0

Без проблем Марк. Мы ценим ваш вклад. Теперь это выглядит отлично с вашим последним правлением. – SBirthare

0

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

Если это так, используя отражение для обработки, это будет похоже на использование кувалды, чтобы взломать гайку, и обновление каждого свойства вручную стало бы ненужным kludge. Простой причиной этого является отслеживание изменений, которое реализовано как Linq to Sql, так и Entity Framework.Все, что вам нужно сделать, это:

  • Инстанцировать в ERPDataContext и сохранить его живым

  • Получить строку, которую вы хотите изменить и назначить новые значения для него

  • Позвоните SubmitChanges()

ORM затем обновит исходную строку в базе данных по мере ее возникновения keeps track оригинальных и новых значений в сущности.

Пример (со всем кодом инлайн):

using (var context = new ERPDataContext()) 
{ 
    var STD = context.STUDENTs.SingleOrDefault(obj=>obj.ID==idToLookup); 

    if (STD != null) 
    { 
     STD.SomeValue = someValue; 
    } 

    context.SubmitChanges(); // submit *CHANGES* 
} 
Смежные вопросы