Home > Net >  Clone new object of old object without old reference in C#
Clone new object of old object without old reference in C#

Time:01-28

I have a huge object with a lot of attributes and child objects. Because of a poorly designed database which I can't control, I need to find matching objects in allCourses with the attribute CourseType = "SVYE". For those who matches the condition, I want to change all values from "SVYE" to "SVYR" instead and add them to the original object allCourses.

I realized that when you declare svCourse you still have the old references in courses which will cause all objects with the value on CourseType = "SVYR". Instead of every match should be one with CourseType = "SVYE" and one with CourseType = "SVYR".

How could I create a copy of the matching values without having the reference to allCourses in the new var svCourses without declaring every attribute again?

new Course(){

name = a.name
// etc..
} 

 

My code:

  var svCourses = allCourses.Where(x => x.Occasions
                  .Any(y => y.CourseType.Equals("SVYE")))
                  .ToList();

         
            foreach(var svCourse in svCourses)
            {
                foreach(var o in svCourse.Occasions)
                {
                    o.CourseType = "SVYR";
                }
                allCourses.Add(svCourse);
            }

           

            return allCourses;

CodePudding user response:

If I understand you correctly, you want to keep Courses that have Occasions with CourseType.Equals("SVYE") unchanged in your collection and add a copy of that courses with modified only CourseType (CourseType = "SVYR"). Right?

If so, you must somehow deep-clone the svCourses collection with 3-rd party library:

Json.NET NuGet:

var svCourses = allCourses.Select(x => new 
                {
                  Course = x, 
                  MatchedOccasions = x.Occasions
                                      .Where(y => string.Equals(y.CourseType, "SVYE"))
                                      .ToArray()
                })
                .Where(x => x.MatchedOccasions.Length > 0)
                .ToList();

var clonedSvCourses = JArray.FromObject(svCourses.Select(x => x.Course).ToList()).ToObject<List<Course>>();

allCourses.AddRange(clonedSvCourses);

foreach(var occasion in svCourses.SelectMany(x => x.MatchedOccasions))
{
   occasion.CourseType = "SVYR";
}

return allCourses;

FastDeepCloner NuGet I think, can be used too.

CodePudding user response:

I found a solution on my own!

I used a third-party library called CloneExtensions. This library could be used to create a deep copy of your object without declaring every attribute. This new variable newCourses which is a deep copy of svCourses doesn't have the old reference to allCourses, which solves the problem.

This solution will replace o.CourseType = "SVYR"; for all ocassions in the variable newCourses.

  var svCourses = allCourses.Where(x => x.Occasions
      .Any(y => y.CourseType.Equals("SVYE")))
      .ToList();

  var newCourses = svCourses.Select(x => 
      CloneExtensions.CloneFactory.GetClone(x));
        
     
        foreach(var svCourse in newCourses)
        {
            foreach(var o in svCourse.Occasions)
            {
                o.CourseType = "SVYR";
            }
            allCourses.Add(svCourse);
        }

       

        return allCourses;

CodePudding user response:

Any means Determines whether any element of a sequence satisfies a condition.

What you need is

  1. List all occasions of all courses.

  2. Choose occasions that CourseType = SVYE

var svCourses = allCourses
    .SelectMany(c => c.Occasions)
    .Where(o => o.CourseType.Equals("SVYE"))
    .ToList();
  •  Tags:  
  • Related