首先,您需要使用类似的方法来选择要更新的实体:
var widget = db.Widgets.First(p => p.ID == 1);
var widget_diff = db.Widgets_Changes.First(p => p.ID == 1);
现在您可以简单地使用反射来更新所有字段:
foreach(var toProp in typepf(Widget).GetProperties())
{
var fromProp= typeof(Widget_Change).GetProperty(toProp.Name);
var toValue = fromProp.GetValue(widget_diff, null);
if (toValue != null)
{
toProp.SetValue(widget, toValue, null);
}
}
通过预先构建属性列表可以加快速度,因此您只需使用反射一次:
public static class WidgetUtil
{
public static readonly IEnumerable<Tuple<PropertyInfo, PropertyInfo>> PropertyMap;
static Util()
{
var b = BindingFlags.Public | BindingFlags.Instance;
PropertyMap =
(from f in typeof(Widget).GetProperties(b)
join t in typeof(WidgetChange).GetProperties(b) on f.Name equals t.Name
select Tuple.Create(f, t))
.ToArray();
}
}
...
foreach(var propertyPair in WidgetUtil.PropertyMap)
{
var toValue = propertyPair.Item2.GetValue(widget_diff, null);
if (toValue != null)
{
propertyPair.Item1.SetValue(widget, toValue, null);
}
}
如果您有许多这样的实体类型,您甚至可能需要考虑将其制作为通用实用程序:
public static class WidgetUtil<T1, T2>
{
public static readonly IEnumerable<Tuple<PropertyInfo, PropertyInfo>> PropertyMap;
static WidgetUtil()
{
var b = BindingFlags.Public | BindingFlags.Instance;
PropertyMap =
(from f in typeof(T1).GetProperties(b)
join t in typeof(T2).GetProperties(b) on f.Name equals t.Name
select Tuple.Create(f, t))
.ToArray();
}
}