I need to split a packet
bases on some Rules and Name which I need to match with different list NameOwnersBasedOnRule
.
I have a class NameOwnersBasedOnRule
where I have defined my different set of RuleOwner for a Name, number of Rule and Owner are NOT fixed for each Name.
var nameOwnersBasedOnRule = new List<NameOwnersBasedOnRule>
{
new NameOwnersBasedOnRule
{
Name = "Name1", Owners = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Rule1", "Owner1"),
new KeyValuePair<string, string>("Rule2", "Owner2"),
new KeyValuePair<string, string>("Rule3", "Owner3")
}
},
new NameOwnersBasedOnRule
{
Name = "Name2", Owners = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Rule2", "Owner2")
}
},
new NameOwnersBasedOnRule
{
Name = "Name3", Owners = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Rule1", "Owner1"),
new KeyValuePair<string, string>("Rule1", "Owner2"),
new KeyValuePair<string, string>("Rule1", "Owner3")
}
}
};
I have list of packet
and each packet has some Rule
associates with it and the Name
is part of nested InstanceData
and may be repeated for multiple InstanceName. Here is one sample data packet,
var dataPacket = new Packet
{
Id = new Guid("2e08bd98-68eb-4358-8efb-9f2adedfb034"),
Rules = new List<string> { "Rule1", "Rule2" },
Results = new Result
{
ResultName = "ResultName1",
Instances = new List<Instance>
{
new Instance
{
InstanceName = "InstanceName1",
InstanceDatas = new List<InstanceData>
{
new InstanceData{Name = "Name1", Value = "V1"},
new InstanceData{Name = "Name2", Value = "V2"},
new InstanceData{Name = "Name3", Value = "V3"},
new InstanceData{Name = "Name4", Value = "V4"}
}
},
new Instance
{
InstanceName = "InstanceName2",
InstanceDatas = new List<InstanceData>
{
new InstanceData{Name = "Name1", Value = "V5"},
new InstanceData{Name = "Name2", Value = "V6"},
new InstanceData{Name = "Name3", Value = "V7"},
new InstanceData{Name = "Name4", Value = "V8"}
}
}
}
}
};
- This packet have more than one Name and I need to split it based on matching rule and name from
List<NameOwnersBasedOnRule>
and need to distribute the the associated owners.
For above data example packet I have 2 rules "Rule1", "Rule2", hence
Name1 should be distributed to Owner1 and Owner2.
Name2 only to Owner2.
Name3 to all owners Owner1, Owner2, Owner3
'Name4` to NONE
Expected data for each owner should be like this,
var owner1Data = new Packet
{
Id = new Guid("2e08bd98-68eb-4358-8efb-9f2adedfb034"),
Results = new Result
{
ResultName = "ResultName1",
Instances = new List<Instance>
{
new Instance
{
InstanceName = "InstanceName1",
InstanceDatas = new List<InstanceData>
{
new InstanceData{Name = "Name1", Value = "V1"},
new InstanceData{Name = "Name3", Value = "V3"}
}
},
new Instance
{
InstanceName = "InstanceName2",
InstanceDatas = new List<InstanceData>
{
new InstanceData{Name = "Name1", Value = "V5"},
new InstanceData{Name = "Name3", Value = "V7"}
}
}
}
}
};
var owner2Data = new Packet
{
Id = new Guid("2e08bd98-68eb-4358-8efb-9f2adedfb034"),
Results = new Result
{
ResultName = "ResultName1",
Instances = new List<Instance>
{
new Instance
{
InstanceName = "InstanceName1",
InstanceDatas = new List<InstanceData>
{
new InstanceData{Name = "Name1", Value = "V1"},
new InstanceData{Name = "Name2", Value = "V2"},
new InstanceData{Name = "Name3", Value = "V3"}
}
},
new Instance
{
InstanceName = "InstanceName2",
InstanceDatas = new List<InstanceData>
{
new InstanceData{Name = "Name1", Value = "V5"},
new InstanceData{Name = "Name2", Value = "V6"},
new InstanceData{Name = "Name3", Value = "V7"},
}
}
}
}
};
var owner3Data = new Packet
{
Id = new Guid("2e08bd98-68eb-4358-8efb-9f2adedfb034"),
Results = new Result
{
ResultName = "ResultName1",
Instances = new List<Instance>
{
new Instance
{
InstanceName = "InstanceName1",
InstanceDatas = new List<InstanceData>
{
new InstanceData{Name = "Name3", Value = "V3"}
}
},
new Instance
{
InstanceName = "InstanceName2",
InstanceDatas = new List<InstanceData>
{
new InstanceData{Name = "Name3", Value = "V7"}
}
}
}
}
};
Here all the class structure I have,
public class NameOwnersBasedOnRule
{
public string Name { get; set; }
public List<KeyValuePair<string, string>> Owners { get; set; }
}
public class Packet
{
public Guid Id { get; set; }
public List<string> Rules { get; set; }
public Result Results { get; set; }
}
public class Result
{
public string ResultName { get; set; }
public List<Instance> Instances { get; set; }
}
public class Instance
{
public string InstanceName { get; set; }
public List<InstanceData> InstanceDatas { get; set; }
}
public class InstanceData
{
public string Name { get; set; }
public string Value { get; set; }
}
Note -
This below method split my big packet
by Name
.
private static IEnumerable<Packet> SplitByName(Packet packet)
{
var names = packet.Results.Instances
.SelectMany(it => it.InstanceDatas)
.Select(it => it.Name)
.Distinct()
.ToList();
IList<Packet> result = new List<Packet>();
foreach (var name in names)
{
var newInstances = packet.Results.Instances
.Select(it => new Instance
{
InstanceName = it.InstanceName,
InstanceDatas = it.InstanceDatas
.Where(it1 => it1.Name == name)
.ToList()
})
.Where(it => it.InstanceDatas.Any())
.ToList();
var newResult = new Result
{
ResultName = packet.Results.ResultName,
Instances = newInstances
};
result.Add(new Packet
{
Id = packet.Id,
Results = newResult
});
}
return result;
}
Can we then prepare required result for each owner in one query?
See Question&Answers more detail:
os