Puis-je interroger un UserType avec plusieurs propriétés mises en correspondance avec une seule colonne?

StackOverflow https://stackoverflow.com/questions/5845693

  •  27-10-2019
  •  | 
  •  

Question

Je le modèle de domaine suivant:

public class Name
{
    private readonly string fullName;
    public Name(string fullName) { this.fullName = fullName }
    public string FullName { get { return fullName; } }
    public string FirstName { get { /* ... */ } }
    public string MiddleNames { get { /* ... */ } }
    public string LastName { get { /* ... */ } }
    public static implicit operator Name(string name) { /* ... */ }
}

public class Person
{
    public Name BirthName { get; set; }
    public Name Pseudonym { get; set; }
}

Je mis en œuvre IUserType donc je peux mapper chaque nom à une seule colonne de base de données avec le nom complet.

Requêtes comme ce travail:

var people = session.QueryOver<Person>()
                    .Where(p => p.Name == "John Doe")
                    .List();

Mais je ne peux pas question comme ceci:

var people = session.QueryOver<Person>()
                    .Where(p => p.Name.LastName == "Doe")
                    .List();

Puis-je faire du travail NHibernate avec cela?

Était-ce utile?

La solution

Je ne suis pas beaucoup plus d'un utilisateur NHibernate, mais l'analyse de toutes les informations que nous avons ici sur le scénario, j'ai un fort sentiment que la réponse est que vous ne pouvez pas.

Vous mappez la valeur contenue dans cette classe à une valeur unique dans la db.

Pour cela pour permettre l'interrogation sur ses morceaux, il faudrait comprendre comment tous ces sous éléments d'information dans la classe Nom sont liés à la pleine valeur.

Ce serait dire comprendre ce que le code c # personnalisé vous y fait.


mise à jour 1:

Au-dessus de réponse est tout au sujet d'avoir généré automatiquement pour vous et en utilisant la dernière requête que vous y avez mentionné.

Vous pouvez certainement contourner le problème comme suggéré par @cs. Autrement dit, la définition d'une fonction définie par l'utilisateur qui fait ce que vous voulez, et que la cartographie NHibernate.

À tout le moins que vous permet le faire faire quelque chose comme:

session.QueryOver<Person>()
        .Where(p => session.PersonLastName(p) == "Doe")
        .List();

Une autre façon serait de définir une méthode d'extension qui est traduit à ce que vous voulez, la mise en œuvre comme dans cet article: http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-extension.html

Utilisation serait alors comme:

 session.QueryOver<Person>()
     .Where(p=> p.Name.LastNameExt() == "Doe")// Ext just to avoid name collision
     .List();

Enfin, je ne sais pas s'il est possible de cartographier les propriétés sous à des fonctions définies par l'utilisateur pour chaque, afin que votre requête peut rester inchangée comme:

 session.QueryOver<Person>()
                .Where(p => p.Name.LastName == "Doe")
                .List();

Non que dans tous les cas, vous changez de données concaténer à l'analyse des données. Vous êtes le seul à savoir si cela est vraiment acheter quelque chose, par rapport à garder les propriétés séparément.

Autres conseils

Je crois qu'il est possible, mais il faudra un peu de travail sur le côté SQL des choses. La première chose que je voudrais probablement essayer de créer une UDF d'une sorte qui va diviser le nom pour vous et faire la comparaison nécessaire. Vous pouvez ensuite étendre NHibernate à la carte à cette UDF et vous devraient pouvoir invoquer cette fonction de votre requête, que ce soit SQL, HQL, ou sur la base ICriteria.

Vous ne pourrez requêter le nom complet, en raison de son être juste un champ de base de données.

Si vous associez différemment de sorte que prenom et nomFamille sont des colonnes distinctes, vous devriez être en mesure d'interroger sur chacun d'eux, mais vous pourriez alors l'interrogation de difficulté sur une propriété appelée FullName.

Vous devez créer des colonnes calculées. Ils seront en lecture seule, mais vous pouvez interroger contre eux. Voir .

Ce que vous pouvez faire est de mettre en œuvre votre propre emballage référentiel pour ces objets et mettre en œuvre des méthodes telles que GetUsersByLastName () qui pourraient utiliser HQL pour effectuer ces types de requêtes « recherche par valeur partielle ».

Quelque chose comme ce qui suit devrait vous permettre de rechercher par une valeur partielle à condition que vous passez dans la chaîne de recherche à droite:

var hql = "select p from People p where lower(p.BirthName) like :searchText";

Edit:

Suppression de LastName requête. La façon dont cela fonctionnerait est vous utiliser le texte de recherche soit ancrée au début ou à la fin du champ BIRTHNAME. Par exemple, si vous voulez rechercher toutes les personnes avec le dernier nom de Smith que vous pourriez faire:

var hql = "select p from People p where lower(p.BirthName) like '% smith'";

Et dans le cas des personnes avec le prénom Joe:

var hql = "select p from People p where lower(p.BirthName) like 'joe %'";
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top