J'ai déjà pensé à la façon dont je vais résoudre ce problème en roulant ma propre solution, mais je me demandais si .net a déjà la fonctionnalité de ce que j'essaie de monter - si oui, je préfère utiliser quelque chose Intégré.
Supposons que j'ai deux instances d'un objet Je veux fusionner celles-ci pour créer ce qui suit: p> widget code>, appelons-les partita code> et partie code>. Les informations de chacun ont été recueillies à partir de deux services Web différents, mais les deux ont des identifiants correspondants. P> List<Widget> Result = PartA.MergeWith(PartB).MergeObjectsOn(Widget.ID).toList();
3 Réponses :
Vous pouvez écrire votre (s) méthode (s) d'extension), quelque chose comme ceci: où Mise en œuvre, par exemple Comme: p> alors c'est aussi simple que icanmerge code> est comme: p> partita.mergewith (partb) .tolist () code>. p> p>
Façon de faire le mile supplémentaire, tim! J'attendais un point dans la bonne direction, mais vous semblez avoir fourni une solution (et bien mieux que ce que j'utilise actuellement). Merci beaucoup :). Je vais essayer cela et revenir à vous avec un "accepter".
Quand j'ai essayé cela, cela ne me permet que de fusionner contre l'objet (par exemple, un widget), pas contre toute la liste, ce qui signifierait faire une forise et faire la fusion de chaque article (après avoir trouvé un match pour chacun). À peu près sûr que ce n'est pas c'était censé être utilisé, mais pourquoi ne pas fusionner l'une de mes options comme une extension pour des listes ienumérables?
@mppowe avez-vous changé-le à cette source T code> au lieu de de cette source
Peu importe ... Je ne sais pas pourquoi ce n'était pas montrant auparavant, maintenant c'est. Peut-être que je n'ai pas donné à Intellisense une chance de se rattraper ou de quelque chose. Quoi qu'il en soit, oui ça a fonctionné. Une chose à noter est que si les listes sont de tailles différentes, la première liste (Parta dans l'exemple ci-dessus) doit être la plus petite. Sinon, vous obtenez une phrase clésFoundException. Merci encore pour le code ci-dessus Tim, c'est assez cool
Si vos listes sont une pour une (c'est-à-dire le même nombre d'éléments et chaque élément de la liste Parta contient une correspondance dans la liste Partb), je considérerais ensuite le zip extension. Notez que ZIP n'exige pas que chaque liste ait le même nombre d'éléments. Toutefois, si vous ne pouvez pas compter sur des éléments "associe" avec des identifiants correspondants, mon approche simpliste ne fonctionnera pas.
vous pouvez faire quelque chose comme ceci: p> Si vous souhaitez que votre LINQ soit plus propre, vous pouvez encapsuler le widget individuel de la logique dans une méthode de fonction ou d'extension. qu'au lieu du délégué en ligne. p> p>
var source = new List<MediaFolder>
{
new MediaFolder
{
Id = "Id1",
Name = "Name1",
Path = "Path1"
},
new MediaFolder
{
Id = "Id2",
Name = "Name2",
Path = "Path2"
},
new MediaFolder
{
Id = "Id3",
Name = "Name3",
Path = "Path3"
},
new MediaFolder
{
Id = "Id4",
Name = "Name4",
Path = "Path4"
},
new MediaFolder
{
Id = "Id5",
Name = "Name5",
Path = "Path5"
},
new MediaFolder
{
Id = "Id6",
Name = "Name6",
Path = "Path6"
}
};
var target = new List<MediaFolder>
{
new MediaFolder
{
Id = "Id1",
Name = "Actualizado en el objeto",
Path = "Path1"
},
//Id2 eliminado
new MediaFolder
{
Id = "Id3",
Name = "Name3",
Path = "Actualizado tambien"
},
new MediaFolder
{
Id = "Id4",
Name = "Name4",
Path = "Path4"
},
new MediaFolder
{
Id = "Id5",
Name = "Name5",
Path = "Path5"
},
new MediaFolder
{
Id = "Id6",
Name = "Name6",
Path = "Path6"
},
new MediaFolder
{
Id = "Id7",
Name = "Nuevo Item 7",
Path = "Nuevo Item 7"
}
};
var merge = source.Merge(target, (x, y) => x.Id == y.Id);
var toUpdate = merge.Matched((x, y) => x.Name != y.Name | x.Path != y.Path)
.ToArray();
var toDelete = merge.NotMatchedBySource();
var toInsert = merge.NotMatchedByTarget();
Assert.AreEqual(2, toUpdate.Count());
Assert.IsTrue(toUpdate.Count(x => x.Source.Id == "Id1" & x.Target.Id == "Id1") > 0);
Assert.IsTrue(toUpdate.Count(x => x.Source.Id == "Id3" & x.Target.Id == "Id3") > 0);
Assert.AreEqual("Id7", toInsert.First().Id);
Assert.AreEqual("Id2", toDelete.First().Id);
Juste une façon vraiment non intelligente de le faire. Complètement manuel: boucle à travers chaque liste et créer une nouvelle liste d'objets fusionnés - que j'ai également fusionné manuellement (c'est-à-dire codé dur). Cela fait le travail, mais ça craint vraiment et sera gênant de maintenir. Je cherche une meilleure façon.