Praveen Rao Chavan.G
Praveen Rao Chavan.G

Reputation: 2860

Clone a object with all child nodes with a new GUID in c#

Let's consider the is a Incident Object, this object consists of various sub-object, all these are stored in different respective tables in Postgres SQL, I am using entity framework core to save it to DB.

public partial class Incident
    {
        public Incident()
        {
            InverseRefIncident = new HashSet<Incident>();
            MaintTaskIncidentIncidentIdExecuteNavigation = new HashSet<MaintTaskIncident>();
            MaintTaskIncidentIncidentIdPrepareNavigation = new HashSet<MaintTaskIncident>();
            IncidentComment = new HashSet<IncidentComment>();
            IncidentConsumable = new HashSet<IncidentConsumable>();
            IncidentDigitalSigns = new HashSet<IncidentDigitalSigns>();
            IncidentDocument = new HashSet<IncidentDocument>();
            IncidentHazard = new HashSet<IncidentHazard>();
            IncidentMitigation = new HashSet<IncidentMitigation>();
            IncidentPpe = new HashSet<IncidentPpe>();
            IncidentRec = new HashSet<IncidentRec>();
            IncidentResDocs = new HashSet<IncidentResDocs>();
            IncidentSkill = new HashSet<IncidentSkill>();
            IncidentStep = new HashSet<IncidentStep>();
            IncidentStmt = new HashSet<IncidentStmt>();
            IncidentTestEqpt = new HashSet<IncidentTestEqpt>();
        }

        public Guid IncidentId { get; set; }
        public string IncidentName { get; set; }
        public Guid MaintActionId { get; set; }
        public Guid? RefIncidentId { get; set; }
        public Guid IncidentLevel { get; set; }
        public bool? IsIncidentLocked { get; set; }
        public Guid CreateUser { get; set; }
        public DateTime CreateTs { get; set; }
        public Guid UpdateUser { get; set; }
        public DateTime UpdateTs { get; set; }
        public bool? IsDraft { get; set; }

        public virtual MaintAction MaintAction { get; set; }
        public virtual Incident RefIncident { get; set; }
        public virtual IncidentLevel IncidentLevelNavigation { get; set; }
        public virtual ICollection<Incident> InverseRefIncident { get; set; }
        public virtual ICollection<MaintTaskIncident> MaintTaskIncidentIncidentIdExecuteNavigation { get; set; }
        public virtual ICollection<MaintTaskIncident> MaintTaskIncidentIncidentIdPrepareNavigation { get; set; }
        public virtual ICollection<IncidentComment> IncidentComment { get; set; }
        public virtual ICollection<IncidentConsumable> IncidentConsumable { get; set; }
        public virtual ICollection<IncidentDigitalSigns> IncidentDigitalSigns { get; set; }
        public virtual ICollection<IncidentDocument> IncidentDocument { get; set; }
        public virtual ICollection<IncidentHazard> IncidentHazard { get; set; }
        public virtual ICollection<IncidentMitigation> IncidentMitigation { get; set; }
        public virtual ICollection<IncidentPpe> IncidentPpe { get; set; }
        public virtual ICollection<IncidentRec> IncidentRec { get; set; }
        public virtual ICollection<IncidentResDocs> IncidentResDocs { get; set; }
        public virtual ICollection<IncidentSkill> IncidentSkill { get; set; }
        public virtual ICollection<IncidentStep> IncidentStep { get; set; }
        public virtual ICollection<IncidentStmt> IncidentStmt { get; set; }
        public virtual ICollection<IncidentTestEqpt> IncidentTestEqpt { get; set; }
    }

PROBLEM

I want to clone this entire object and just change Id in each level with new GUID's so that I can save a new entry of Incident, I need to change not only Incident ID but also all other ids like CommentID , ConsummableID etc.

What I have tried?

I know its possible to achieve this by creating a new object and mapping through each object in Incident but I was looking like is there a better way to do this?

Appreciate the responses.

Upvotes: 0

Views: 596

Answers (2)

DRFredy
DRFredy

Reputation: 36

Maybe you can create another .cs file into another folder within your project (where the scaffolding process shouldn't make any modification) and extend your class functionality as partial class in this new .cs file.

You have your DB first approach generated file containing the class, which starts with

public partial class Incident
{
    public Incident()
    {

So, you have a green light to extend the class..

This way you could apply the solution given by Ipsit Gaur, but in another file, where you extend you partial class.. So, the resulting code for the new .cs file (the file that contains the partial class extension, the one that the scaffolding process probably wouldn't touch) would be something like this (based on Ipsit Gaur suggestions, but not repeating the properties declarations):

public partial class Incident: ICloneable {
    object ICloneable.Clone() {
        return new Incident {
            IncidentID = Guid.NewGuid,  // New ID 
            Name = this.Name            // Keeping the exising value 
        };
    }
}

Hope this helps or at least open the door for any other idea to find a solution.

Upvotes: 0

Ipsit Gaur
Ipsit Gaur

Reputation: 2927

You need to implement ICloneable interface in each of your class and implement Clone method in such a way that it sets ID to new Guid and keeps the rest values same of the existing object, after that you just need to call Clone method on your parent object. That's it!

e.g-

public class Incident: ICloneable {
    public Guid IncidentID {get; set;}
    public string Name {get; set;}

    object ICloneable.Clone() {
        return new Incident {
            IncidentID = Guid.NewGuid,  // New ID 
            Name = this.Name            // Keeping the exising value 
        };
    }
}

Upvotes: 2

Related Questions