Reputation: 898
I'm trying to come up with a way to reassign all child tables to another parent table. I am currently using EntityFramework 5 to interact with my database. While it won't necessarily be as efficient using EF, this operation rarely occurs.
That said, to do a basic change of a parent object using EntityFramework is straight forward:
objChild.Parent = objNewParent;
When SaveChanges() is called, the Foreign Key is properly updated.
How can I get ALL related entities so I can iterate over them to assign the new parent object? I know this will require Reflection, but so far I've been unable to cobble together anything usable.
I am not concerned with performance. Number of calls to the database, total volume of data loaded, memory or cpu use is not relevant to this answer. They key is the generic nature of not knowing which tables will be present.
Basically, I'm trying to do this but for ALL related records, rather than a single type:
var sourceParents = ParentRecords.Where(n => sourceIds.Contains(n.Id));
var targetParent = Participants.Find(targetId);
var childRecords = sourceParents.SelectMany(n => n.ChildRecords).ToArray();
foreach (var child in childRecords) {
child.ParentRecord = targetParent;
}
Upvotes: 1
Views: 1371
Reputation:
The fact that LINQ usually involves a smaller amount of code tends to be misunderstood as delivering a more efficient solution.
What your current code does:
ParentRecords
to get the list of parents ->
var sourceParents = ParentRecords.Where(n =>
sourceIds.Contains(n.Id));
sourceParents
to get the list of children -> sourceParents.SelectMany(n => n.ChildRecords).ToArray();
childRecords
to change the parent for each children -> foreach...
As far as the first two iterations refer to the same objects (although to different sub-elements), your code can be reduced to just two loops:
var targetParent = Participants.Find(targetId);
foreach (var parent in ParentRecords)
{
if (parent == null) continue;
if (sourceIds.Contains(parent.Id))
{
//Assigning the new parent to all the children
foreach (var child in parent.ChildRecords)
{
if (child == null) continue;
child.ParentRecord = targetParent;
}
}
}
I don't think that you can do things faster under the current conditions (other than by moving to more efficient Types
, relying on approaches maximising the hardware-resources or changing the input data structure to allow more efficient update operations). In case of having a function on the lines of update_the_parents_for_all_my_records()
, bear in mind that it would basically do the same thing: iterate through all the elements. Small-code-size approaches can be fine under certain conditions but tend to be less adaptable than big-code ones. In any case, they shouldn't be misunderstood: the length of the code is not directly related to its actual efficiency (i.e., what the code is actually doing in each case).
Upvotes: 2