9
votes

Mappage d'une liste à une chaîne délimitée avec NHibernate fluide

Mon modèle ressemble à ceci:

public class Product
{
    public string Name {get; set;}
    public string Description {get; set;}
    public double Price {get; set;}
    public List<string> Features {get; set;}
}


0 commentaires

3 Réponses :


0
votes

J'ai mis en place quelque chose de similaire pour le type de données Set MySQL, qui est une liste séparée par des virgules dans la DB mais une liste de chaînes dans le modèle d'entité. Il impliquait à l'aide d'un type de données personnalisé dans NHibernate, basé sur la classe PrimiRetype. Vous faites citer cela à l'aide des mappages et de la méthode .CustomType () sur une carte.

Si vous voulez, je peux vous envoyer un code Snipet pour la classe personnalisée.


0 commentaires

0
votes

J'ai également mis en place quelque chose de similaire pour une structure Point3D. Comme CDMDotNet a déclaré que vous souhaitez essentiellement implémenter et iSerType qui emballera / décompressez les fonctions dans une seule chaîne via les méthodes nullsafeset / nullsafeget.

Vous devrez peut-être aussi mettre en œuvre la méthode égale (), qui est un peu subtile. La raison pour laquelle il est préférable d'illustrer le mieux par un exemple: xxx

La chose est, NHibernate sur l'hydratation stocke une référence à P.Features et la compare à la valeur de P.Features sur une demande d'enregistrement. Pour les types de propriétés immuables, c'est bien, mais dans l'exemple ci-dessus, ces références sont identiques, la comparaison effective est donc xxx

évidemment une implémentation standard de ce dernier retournera toujours fausse.

Comment une affaire-t-elle? Je n'ai aucune idée de la meilleure pratique, mais les solutions sont:

  • faire iusertype.equals (objet x, objet y) retourne toujours faux. Cela obligera la chaîne emballée à reconstruire et un appel de base de données à faire à chaque fois que le produit est enregistré, il est irrégulier de savoir si le produit a été changé sémantiquement ou non. Il s'agit ou non d'un problème dépend d'un nombre de facteurs (taille / nombre d'objets de fonctionnalité, si des objets de produit sont enregistrés lorsqu'il n'est pas modifié, combien d'objets de produits que vous avez, etc.).

  • Fonctionne une iliste et implémente un changeAwaRelist : ilist qui est capable de suivre les modifications (ou de conserver une copie de son original) au courant. Implémentez Iusertype.equals (Object X, Object Y) pour vérifier si X / Y est changeArelist et implémentez la logique nécessaire pour voir si la liste a vraiment changé. C'est la solution que je suis allé avec à la fin.

  • Peut-être que vous pourriez réutiliser le code du type NHibernate GenericListType. À l'époque, j'ai mis en place la solution précédente, je n'avais pas assez d'expérience pour avoir un aller à cela.

    Si vous avez une expérience antérieure avec NHibernate, j'espère que cela devrait vous aider à démarrer. Si ce n'est pas le moi savoir et je vais essayer de mettre en place une solution plus verbeuse.


0 commentaires

12
votes

Je fais la même chose dans mon projet actuel, seulement je persiste une collection d'énums en tant que nombres délimités par pipe. Cela fonctionne de la même manière.

public class Product
{
    protected string _features; //this is where we'll store the pipe-delimited string
    public List<string> Features {
        get
        {
            if(string.IsNullOrEmpty(_features)
                return new List<String>();
            return _features.Split(new[]{"|"}, StringSplitOptions.None).ToList();
        }
        set
        {
            _features = string.Join("|",value);
        }
    }
}

public class ProductMapping : ClassMap<Product>
{
    protected ProductMapping()
    {
        Map(x => x.Features).CustomType(typeof(string)).Access.CamelCaseField(Prefix.Underscore);
    }
}


4 commentaires

J'aime ta solution mais j'aimerais poser une question. Vous exposez la propriété Caractéristiques sous forme de liste suggérant qu'il peut être manipulé à l'aide de Ajouter et Supprimer etc. Est-ce que votre la liste vraiment faire ça. Sinon, pourquoi ne pas exposer un iEnumerable ?


Très bon point - cela aurait plus de sens en fait. J'utiliserais des méthodes d'assistance pour ajouter et supprimer.


@Danb, désolé de creuser un ancien poste: vous déclarez que vous persistez une collection d'énums, mais ce n'est pas clair pour moi où vous tirez cette collection dans cette solution. Juste pour référence, vous pouvez vérifier ce message pour voir ce que je fais: Stackoverflow.com/questions/14288249/...


+1 Pour l'utilisation de l'option de cartographie fluide de .access que je n'étais pas au courant. Vérification aussi vérifier Iusertype, il y a un exemple ici Stackoverflow.com/a/14343650/2181514 qui peut facilement être converti d'une liste pour énumérer .