如何在LINQ中将对象的所有属性复制到另一个属性

时间:2014-02-10 05:13:33

标签: c# linq asp.net-mvc-4

我有一个STUDENT表对象,其中我有新值,我想用这些新值更新STUDENT表。我的代码是下面给出的(它用于将属性从STD复制到getdata但是)它没有更新数据库中STUDENT表中的值为什么?先感谢您。

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

5 个答案:

答案 0 :(得分:7)

你可以在这里使用反射。不确定它是否能彻底解决您的问题。使用反射也可能是一种过度杀伤,所以请检查性能。

我使用了一个虚拟类“A”来解释如何使用它。看看它,让我知道它是否有效。

    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;

希望这有帮助。

答案 1 :(得分:4)

您必须手动更新所有属性:

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

答案 2 :(得分:3)

以下是@ 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);
            }
        }
    }

答案 3 :(得分: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();

答案 4 :(得分:0)

由于您尝试用于更新值的STD对象是一个实体类,我认为可以合理地假设您已发出查询,更改了一些数据,现在希望将更改发送回数据库中。

如果是这样的话,使用反射来处理这个问题就像使用大锤破解螺母一样,手动更新每个属性将是一个不必要的障碍。原因很简单,就是更改跟踪,它由Linq到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*
}