2010-06-16 4 views
2

Quelqu'un at-il rencontré un scénario dans lequel vous deviez fusionner un objet avec un autre objet de même type, fusionnant le graphe d'objet complet. par exemple. Si j'ai un objet personne et un objet personne a le prénom et l'autre le nom de famille, un moyen de fusionner les deux objets en un seul objet.Fusionner un graphique d'objet .net

public class Person 
{ 
    public Int32 Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

public class MyClass 
{ 
    //both instances refer to the same person, probably coming from different sources 
    Person obj1 = new Person(); obj1.Id=1; obj1.FirstName = "Tiju"; 
    Person obj2 = new Person(); ojb2.Id=1; obj2.LastName = "John"; 


    //some way of merging both the object 
    obj1.MergeObject(obj2); //?? 
    //obj1.Id // = 1 
    //obj1.FirstName // = "Tiju" 
    //obj1.LastName // = "John" 
} 

J'ai rencontré un tel type d'exigence et j'ai écrit une méthode d'extension pour faire de même. Toutefois, cela fonctionne lorsque la propriété source est null, si la cible l'a, elle le copie dans la source. Il peut encore être amélioré pour fusionner lorsque des incohérences sont présentes, par ex. si FirstName = "Tiju" et FirstName = "John"

Tout commments apprécié.

Merci TJ

+1

Je ne comprends pas votre question. Voulez-vous des commentaires sur la façon dont votre code peut être amélioré? Ou y a-t-il un problème avec le code? –

+0

Ma question est, est-ce que quelqu'un d'autre fait face à de telles exigences, quelles idées ils ont trouvées. –

Répondre

0

Votre code semble très dégueu. Êtes-vous sûr d'avoir besoin d'un tel modèle générique? Avez-vous l'intention de fusionner plus que des objets Person seuls? Et si oui, les exigences de fusion sont-elles exactement les mêmes? Si vous devez fusionner d'autres types, les modifications doivent être fusionnées différemment. Peut-être que vous devriez choisir un design sans réflexion. Voici une autre idée:

public interface IMergable<T> 
{ 
    T MergeWith(T other); 
} 

public interface IEntity 
{ 
    object EntityId { get; } 
} 

public class Person : IMergable<Person>, IEntity 
{ 
    public int Id { get; set; } 

    object IEntity.EntityId { get { return this.Id; } } 

    public Person MergeWith(Person other) 
    { 
     var mergedperson = new Person(); 

     // Do merging here, and throw InvalidOperationException 
     // when objects can not be merged. 

     return mergedPerson; 
    } 
} 

Yur méthode d'extension ressemblerait à quelque chose comme ceci:

public static IEnumerable<T> MergeList<T>(this IEnumerable<T> left, 
    IEnumerable<T> right) 
    where T : IMergable<T>, IEntity 
{ 
    return 
     from leftEntity in left 
     from rightEntity in right 
     where leftEntity.EntityId.Equals(rightEntity.EntityId) 
     select leftEntity.MergeWith(rightEntity); 
} 
+0

Beau design. Y a-t-il une raison 'IEntity.EntityId' est de type object et non int? Je suppose que ceci ne fonctionnera pas quand le type sous-jacent est réellement un type de valeur, parce que 'leftEntity.EntityId == rightEntity.EntityId' est une comparaison des références de boîte de valeurs qui seraient toujours évaluées à false. –

+0

@ 0xA3: bon point. J'ai réparé ceci. J'ai changé cette ligne à 'leftEntity.EntityId.Compare (rightEntity.EntityId)'. La raison pour laquelle 'Entityid' est un objet, parce que je ne savais pas si les entités ID de l'OP étaient toujours de type' int'. Si c'est le cas, le code deviendra un peu plus simple bien sûr. – Steven

+1

Vous pouvez créer 'EntityId' de type' IEquatable 'et utiliser la méthode' Equals() '. Notez que 'object' n'a pas de méthode' Compare() '. –

0

approche de Nice Steven,

oui, je vais la fusion des objets du même type. Oui, j'ai besoin d'un modèle plus générique.

La raison d'être mon architecture ne me permet des relations d'héritage non pas comme ces objets seront simples DTO qui ne sont que des objets légers vient d'envoyer à l'clint d'interface utilisateur pour se lier à. donc ce genre de relations est hors de question. Cette logique sera requise du côté client et pour être exact, mes données proviendront de différentes sources, disons un de system1, et un autre de system2, les deux retourneront le même objet de type, avec des valeurs différentes, je viens de vouloir un moyen de fusionner les deux objets afin que l'information complète puisse être montrée à l'interface utilisateur du client. Il n'y aura aucune sauvegarde de l'interface utilisateur vers le système. Le code doit être générique et ne doit contenir aucune logique de fusion spécifique au type. Il n'y a pas de problème lorsqu'une propriété est nulle dans un objet et pas dans un autre. le problème se pose lorsque les deux auront des valeurs différentes de mêmes propriétés.

par exemple. une source dit que la personne vit aux Etats-Unis et que d'autres disent que la personne vit en France. que faire dans un tel scénario. Bien que ce soit fondamentalement une question à la BA, mais peut-être une sorte d'indice de crédibilité pour chaque source, le mécanisme peut fonctionner.

Si le type a une liste d'autres DTO, le MergeList fusionnera non seulement les enregistrements correspondants, il sera également ajouter des enregistrements non correspondant à la liste.

des commentaires sur rendre le code plus agréable :-)

+0

Cela signifie-t-il que même l'implémentation d'interfaces sur ces DTO est hors de question? Qu'en est-il de les décorer avec un attribut, n'est-ce pas? Ou y a-t-il des changements hors de la question? (Sont-ils générés automatiquement?) Ma méthode 'MergeList' fournie est un peu naïve, elle fait une jointure. Vous avez également besoin d'enregistrements seulement dans la gauche, et les enregistrements seulement dans le droit? – Steven

+0

vous avez raison, pas d'interfaces, et ils sont générés automatiquement. Je ne peux pas utiliser les attributs car ces DTO sont créés en tant que proxies chez le client (mon cas silverlight) car ces types sont exposés via le service Web WCF. Corrigez-moi si je me trompe, je pense que les informations spécifiques à un réseau telles que les attributs ne peuvent pas être transmises à des mandataires. Je veux tous les enregistrements possibles tant qu'ils ont des clés différentes –

0

Pas de réponse directe, mais anonymes cours types pensent la valeur de:

return new { 
    FirstName = "Peter", 
    LastName = "Pen" 
}; 

Pour plus d'informations, this article explique bien la caractéristique; il y a plus sur msdn et wikipedia.

Pour résumer:

  • Ils ne peuvent hériter de l'objet,
  • leurs membres seulement sont des champs privés chacun avec un correspondant propriété en lecture/écriture.
+0

pouvez-vous s'il vous plaît élaborer un peu .. –

Questions connexes