我们的数据库中有一个审计表,在更新时,旧值和新值被序列化为 XML 并存储在同一行中。这些对象目前是深度克隆的:
public EntityObject CloneEntity(EntityObject obj)
{
DataContractSerializer dcSer = new DataContractSerializer(obj.GetType());
MemoryStream memoryStream = new MemoryStream();
dcSer.WriteObject(memoryStream, obj);
memoryStream.Position = 0;
EntityObject newObject = (EntityObject)dcSer.ReadObject(memoryStream);
return newObject;
}
虽然这有效,但由于从深度克隆中提取的相关记录,它会生成大量数据,从 dcSer.WriteObject(memoryStream, obj)
上的数据库读取了数十万次,最终的 MemoryStream 大小约为 200MB,更不用说写回数据库的数据量了。不理想。
所以我想改为执行成员克隆,因为我的理解是成员克隆会忽略对象引用,并避免复制所有相关的 Entity Framework 模型。
所以我这样做了:
public EntityObject CloneEntity(EntityObject obj)
{
EntityObjectAuditable auditable = (EntityObjectAuditable)obj; // invalid cast exception
return auditable.ShallowCopy();
}
// ....
public class EntityObjectAuditable : EntityObject
{
public EntityObjectAuditable ShallowCopy()
{
return (EntityObjectAuditable)this.MemberwiseClone();
}
}
但我得到一个无效的转换异常,因为传入的 EntityObject
的实际类型是与表本身相关的子类。
我也尝试过使用扩展方法访问 MemberwiseClone()
,但是扩展方法无法访问 protected 方法。
那么,如何创建通用 EntityObject 的浅拷贝?
最佳答案
我的第一个建议是尝试这个,这与您现在正在做的类似,但对我来说开销很小:
DataContractSerializationUtils.SerializeToXmlString(Entity, throwExceptions);
另外,我以前成功地使用过这种方法,并且没有发现输出太冗长。它似乎与您现在所做的几乎相同。
/// <summary>
/// Creates an exact duplicate of the entity provided
/// </summary>
/// <param name="source">The source copy of the entity</param>
/// <returns>An exact duplicate entity</returns>
public TEntity Clone(TEntity Source)
{
// Don’t serialize a null object, simply return the default for that object
if (ReferenceEquals(Source, null))
{
return default(TEntity);
}
var dcs = new DataContractSerializer(typeof (TEntity));
using (Stream stream = new MemoryStream())
{
dcs.WriteObject(stream, Source);
stream.Seek(0, SeekOrigin.Begin);
return (TEntity) dcs.ReadObject(stream);
}
}
如果这些选项都不吸引人,我的建议是编写一个简短的函数,使用反射从源实体复制任何属性。
关于c# - 创建 EntityObject 子类的浅拷贝/克隆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9695420/