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:
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
List all occasions of all courses.
Choose occasions that
CourseType = SVYE
var svCourses = allCourses
.SelectMany(c => c.Occasions)
.Where(o => o.CourseType.Equals("SVYE"))
.ToList();
