c# - 创建 EntityObject 子类的浅拷贝/克隆

标签 c# .net shallow-copy shallow-clone

我们的数据库中有一个审计表,在更新时,旧值和新值被序列化为 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/

相关文章:

无明显原因使用 Python 列表切片语法

c# - COM 与 VB6 和 C# 互操作

c# - FFMPEG 进程太多

c# - 大型 HTTPResponseMessage 导致 .NET Core 服务器进程内存不足

.net - 如果使用 ChainPolicy RevitationMode Online,X590Certificate.Build 是否使用 OCSP?

language-agnostic - 深拷贝和浅拷贝有什么区别?

ios - 当变量值改变时如何改变 View 的框架?

c# - 查看是否有人登录了 gmail、yahoo 和 facebook

c# - 从 MSMQ 日志读取消息队列发送时间

c# - 尝试使用 .net 4.0 在 XP sp3 上运行 TLS1.2