Kann ich einen Benutzertyp mit mehreren Eigenschaften abfragen, die einer einzigen Spalte zugeordnet sind?

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

  •  27-10-2019
  •  | 
  •  

Frage

Ich habe das folgende Domänenmodell:

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; }
}

Ich habe implementiert IUserType So kann ich jeden Namen einer einzelnen Datenbankspalte mit dem vollständigen Namen zuordnen.

Abfragen wie diese Arbeit:

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

Aber ich kann nicht so abfragen:

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

Kann ich Nhibernate damit zum Laufen bringen?

War es hilfreich?

Lösung

Ich bin nicht viel von einem Nhibernate -Benutzer, aber die Analyse aller Informationen, die wir hier über das Szenario haben, habe ich das starke Gefühl, dass die Antwort Sie nicht können.

Sie machten den in dieser Klasse enthaltenen Wert auf einen einzelnen Wert in der DB ab.

Damit es das Abfragen seiner Stücke ermöglicht, müsste es verstehen, wie all diese Unterteile von Informationen in der Namensklasse mit dem vollständigen Wert zusammenhängen.

Das würde bedeuten, zu verstehen, was der benutzerdefinierte C# -Coder gibt, den Sie dort haben.


Update 1:

Die oben genannte Antwort bezieht sich darauf, dass alles automatisch für Sie generiert wird und die genaue Abfrage verwendet, die Sie dort erwähnt haben.

Sie können definitiv das Problem umgehen, wie dies von @CS vorgeschlagen wurde. Das heißt, eine benutzerdefinierte Funktion zu definieren, die das tut, was Sie wollen, und diese in Nhibernate zuordnen.

Zumindest würde Sie so etwas tun wie:

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

Eine andere Möglichkeit wäre, eine Erweiterungsmethode zu definieren, die auf das übersetzt wird, was Sie wollen, und sie wie in diesem Artikel implementieren: http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-eutsion.html

Verwendung dann wäre wie:

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

Schließlich bin ich mir nicht sicher, ob es möglich ist, die Subeigenschaften für jeweils benutzerdefinierte Funktionen zuzuordnen, damit Ihre Abfrage unverändert bleibt wie:

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

Nicht, dass Sie in allen Fällen von der Verkettungsdaten zum Parsen von Daten wechseln. Sie sind der einzige, der weiß, ob Ihnen das wirklich etwas kauft, im Vergleich zu den Eigenschaften separat.

Andere Tipps

Ich glaube, es ist möglich, muss aber etwas Arbeit auf der SQL -Seite der Dinge erfordern. Das erste, was ich wahrscheinlich versuchen würde, ist, eine Art UDF zu erstellen, das den Namen für Sie aufteilt und den notwendigen Vergleich durchführt. Sie können dann Nhibernate auf diese UDF und Sie ausdehnen sollte In der Lage sein, diese Funktion aus Ihrer Abfrage aufzurufen, egal ob SQL, HQL oder Icriteria basiert.

Sie können nur den vollständigen Namen abfragen, da es sich nur um ein Datenbankfeld handelt.

Wenn Sie es anders zuordnen, sodass FirstName und LastName separate Spalten sind, sollten Sie in der Lage sein, jeweils auf sie abfragen zu können. Sie können jedoch möglicherweise Schwierigkeiten haben, auf einer Eigenschaft namens Fullname abzufragen.

Sie müssen berechnete Spalten erstellen. Sie werden schreibgeschützt sein, aber Sie können gegen sie nachfragen. Sehen hier.

Sie können Ihren eigenen Repository -Wrapper für diese Objekte implementieren und Methoden wie GetUsersBylastName () implementieren, die HQL verwenden könnten, um diese Arten von "Suche nach Teilwert" -Anfragen durchzuführen.

Etwas wie folgt sollte es Ihnen ermöglichen, nach einem Teilwert zu suchen, das Sie in der richtigen Suchzeichenfolge übergeben haben:

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

Bearbeiten:

Lastname aus der Abfrage entfernt. So wie dies funktionieren würde, würden Sie den verankerten Suchtext entweder zum Beginn oder zum Ende des Geburtsname -Feldes verwenden. Wenn Sie beispielsweise nach allen Personen mit Nachnamen von Smith suchen möchten, könnten Sie dies tun:

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

Und im Fall von Personen mit Vorname Joe:

var hql = "select p from People p where lower(p.BirthName) like 'joe %'";
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top