不幸的是,我想不出任何方法来整齐地执行这个更新 - 因为你使用Table Per Concrete Class,我能想到的唯一方法是删除现有的Employee并添加一个新的Manager。说了这么多,我确实有一些可以帮助你的东西 - 我需要它的原因是不同的,但它也可能对你有帮助。
下面的类使用反射来提供通用的“复制”机制。要使用它,试试下面的代码片段(假设员工是员工获得晋升):
var manager = new Manager;
var copier = new PropertyCopier<Employee,Manager>(employee, manager);
copier.Copy();
经理对象现在应具有相同的属性值Employee对象做了(至少在财产存在于两个类)。现在您可以提交经理并删除原始员工。
的PropertyCopier类代码如下:
using System;
using System.Reflection;
// ... You will want this in your own namespace not mine. ;-)
///<summary>
/// Copies properties with the same name and type from one object to another.
///</summary>
///<typeparam name="TFirst">The object type to copy from.</typeparam>
///<typeparam name="TSecond">The object type to copy to.</typeparam>
public class PropertyCopier<TFirst, TSecond>
where TFirst : class
where TSecond : class
{
private readonly TFirst _first;
private readonly TSecond _second;
///<summary>
/// Creates an instance of the PropertyCopier.
///</summary>
///<param name="first">The object to copy properties from.</param>
///<param name="second">The object to copy properties to.</param>
///<exception cref="ArgumentNullException">An <see cref="ArgumentNullException"/> will be thrown if
/// the source or destination objects are null.</exception>
public PropertyCopier(TFirst first, TSecond second)
{
if (first == null)
{
throw new ArgumentNullException("first");
}
if (second == null)
{
throw new ArgumentNullException("second");
}
_first = first;
_second = second;
}
///<summary>
/// Performs the copy operation.
///</summary>
public void Copy()
{
Copy(p => true);
}
///<summary>
/// Performs the copy operation, omitting any items for which the predicate evaluates to false.
///</summary>
///<param name="predicate">A predicate based on the <see cref="PropertyInfo"/> used to determine if the property should be copied.</param>
///<exception cref="ArgumentException">An <see cref="ArgumentException"/> may be thrown if the copy cannot be performed.
/// This may happen if, for example, there is a property with the same name but a different type.</exception>
public void Copy(Predicate<PropertyInfo> predicate)
{
foreach (PropertyInfo info in typeof(TFirst).GetProperties())
{
PropertyInfo infoInDestination = null;
try
{
infoInDestination = typeof(TSecond).GetProperty(info.Name, info.PropertyType);
}
catch (AmbiguousMatchException)
{
}
try
{
if (infoInDestination != null && infoInDestination.CanWrite && predicate(infoInDestination))
{
infoInDestination.SetValue(_second, info.GetValue(_first, null), null);
}
}
catch (Exception e)
{
throw new ArgumentException(String.Format("Unable to copy property called {0}", info.Name), e);
}
}
}
}
希望这有助于!
谢谢,这实际上工作非常好! – Ciel