5

i have a STUDENT table object in which i have new values and i want to update the STUDENT table with these new values. my code is given bellow (which is working for copying properties from STD to getdata but) its not updating the values in STUDENT table in database why? thankyou in advance.

public void UpdateStudent(STUDENT STD)
    {
        context = new ERPDataContext();
        var getdata = context.STUDENTs.SingleOrDefault(obj=>obj.ID==STD.ID);
        getdata = STD;
        context.SubmitChanges();
    }
Yogseh pathak
  • 61
  • 1
  • 1
  • 5
  • 2
    When using reference types (in C# that's almost everything except your basic `int`, `bool` etc), assigning one reference type to another will effectively throw away the old values. In your case you're getting a student, then throwing it away and replacing it with the one you have, which is not attached to the context you're telling to `SubmitChanges()`. – Timothy Walters Feb 10 '14 at 05:19

5 Answers5

8

You can use reflection here. Not very sure if it will solve your problem completely. Also using reflection can be an overkill so please check for performance.

I have used a dummy class "A" to explain how you can use it. Check it out and let me know if it works.

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

And the code is:

        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);
        }

Of course you need to add the namespace:

using System.Reflection;

Hope this helps.

samar
  • 5,021
  • 9
  • 47
  • 71
4

You have to update all properties manually:

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

Otherwise, you're just replacing getdata reference, and do not change the object itself.

Or you can use following:

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();
MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
3

The below is a variation on @samar's answer, but the inner section is wrapped with an if that checks the property CanWrite, otherwise you will get an error.

        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);
       }
    }

Updated with a very generic helper function:

        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);
            }
        }
    }
Mark Tomlinson
  • 117
  • 1
  • 11
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient [reputation](http://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](http://stackoverflow.com/help/privileges/comment). – SBirthare Jul 01 '15 at 06:44
  • 1
    Sbirthare, you must have 50 rep to comment on someones answer. I had no other way to add my info except to add my own answer. Thus i couldn't critique or request clarification directly to samar as mentioned in my answer. – Mark Tomlinson Jul 01 '15 at 23:23
  • No problem Mark. We appreciate your contribution. It now looks fine with your latest edit. – SBirthare Jul 02 '15 at 05:20
1

You should change attached object which is getData object in your case and then call submit changes. If you want to avoid this approach you can use code below:

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

Also you can update properties which has changed:

var getdata = context.STUDENTs.SingleOrDefault(obj=>obj.ID==STD.ID);
getdata.Property = STD.Property;
context.SubmitChanges();
Behrad Farsi
  • 1,110
  • 13
  • 25
0

As the STD object you are trying to use for the updated values is an entity class I think its reasonable to assume you have issued a query, altered some data, and now wish to send the changes back to the database.

If so, using reflection to handle this would be like using a sledgehammer to crack a nut, and updating each property manually would be an unnecessary kludge. The simple reason for this is change tracking, which is implemented by both Linq to Sql and Entity Framework. All you need to do is:

  • Instantiate an ERPDataContext and keep it alive

  • Get the row you wish to alter and assign the new values to it

  • Call SubmitChanges()

The ORM will then update the original row in the database as it keeps track of the original and new values in the entity.

Example (with all code inline):

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

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

    context.SubmitChanges(); // submit *CHANGES*
}
Community
  • 1
  • 1
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108