25. november 2011 - 15:47Der er
3 kommentarer og 1 løsning
lave en omvendt join i nhibernate
Hej
Jeg vil gerne finde alle entities i en tabel hvor de opfylder et antale kriterier og hvor deres id'er IKKE optræder i en anden tabel. Dvs en omvendt join.
Nedenstående funktion fungerer men jeg ville helst lave det i et hug mod databasen
Er der nogen der har en smart metode i nhibernate?
Mvh
Henrik
/// <summary> /// Find alle patienter der er overført til ORTO behandling, siden vi /// søgte sidst, så vi kan oprette dem i det eksterne system /// </summary> private IList<Patient> FindNewOrtoReferredPatients(ISession session, DateTime fromTime, DateTime toTime) { IList<Patient> retVal = new List<Patient>(); var patientRepository = new PatientRepository(session); var patienter = (from x in patientRepository.GetQuery() where x.VisiterTilOrto == true && ( (x.Log.OprettetTid > fromTime && x.Log.OprettetTid < toTime) || (x.Log.RettetTid > fromTime && x.Log.RettetTid < toTime) ) orderby x.Fornavne select x).ToList() ;
// Check mod overført listen 'OrVisiteret', og find ud af om der skal oprettes eller opdateres // Kun hvis de skal oprettes tilføjes de til retVal var ortoVisiteretRepository = new OrtoVisiteretRepository(session); var ortoVisiterede = ortoVisiteretRepository.GetAll(); bool allreadyCreated = false;
// FIXME: det her er noget lort. Det har en worst case O-tid på N^2 - det må sgu da kunne laves i DB direkte foreach (var p in patienter) { foreach (var o in ortoVisiterede) { if (p.Id == o.Patient.Id) { allreadyCreated = true; break; } } if(!allreadyCreated) { retVal.Add(p); } allreadyCreated = false; } return retVal; }
using System; using System.Collections.Generic; using System.Linq;
using MySql.Data.MySqlClient;
using NHibernate; using NHibernate.Cfg; using NHibernate.Linq;
namespace E { public class Person { public virtual string Navn { get; set; } public virtual string Adresse { get; set; } public virtual int Postnr { get; set; } } public class Post { public virtual int Postnr { get; set; } public virtual string Bynavn { get; set; } } public class Program { public static void TestDataReader() { using(MySqlConnection con = new MySqlConnection("Server=localhost;Database=test;User Id=root;Password=")) { con.Open(); MySqlCommand sel = new MySqlCommand("SELECT navn,adresse,postnr FROM person WHERE postnr NOT IN (SELECT postnr FROM post)", con); MySqlDataReader rdr = sel.ExecuteReader(); while(rdr.Read()) { string navn = (string)rdr[0]; string adresse = (string)rdr[1]; int postnr = (int)rdr[2]; Console.WriteLine(navn + " " + adresse + " " + postnr); } rdr.Close(); }
} public static void TestNHibernateHQL() { Configuration cfg = new Configuration(); cfg.Configure("hibernateconfig.xml"); cfg.AddXmlFile("mappings.xml"); ISessionFactory sf = cfg.BuildSessionFactory(); using(ISession s = sf.OpenSession()) { IList<Person> lst = s.CreateQuery("FROM Person AS p WHERE p.Postnr NOT IN (SELECT p2.Postnr FROM Post AS p2)").List<Person>(); foreach(Person p in lst) { Console.WriteLine(p.Navn + " " + p.Adresse + " " + p.Postnr); } } } public static void TestNHibernateLINQ() { Configuration cfg = new Configuration(); cfg.Configure("hibernateconfig.xml"); cfg.AddXmlFile("mappings.xml"); ISessionFactory sf = cfg.BuildSessionFactory(); using(ISession s = sf.OpenSession()) { IList<Person> lst = (from p in s.Query<Person>() where !s.Query<Post>().Select(p2 => p2.Postnr).Contains(p.Postnr) select p).ToList<Person>(); foreach(Person p in lst) { Console.WriteLine(p.Navn + " " + p.Adresse + " " + p.Postnr); } } } public static void Main(string[] args) { TestDataReader(); TestNHibernateHQL(); TestNHibernateLINQ(); Console.ReadKey(); } } }
Tak for hjælpen. Jeg har efter at have prøvet mig lidt frem og tilbage fundet frem til den her løsning som ikke er streng baseret. :)
Hvis der er nogen der vil ave point så smid et svar :)
/// <summary> /// Find alle patienter der er overført til ORTO behandling, siden vi /// søgte sidst, så vi kan oprette dem i det eksterne system /// </summary> private static IList<Patient> FindNewOrtoReferredPatients(ISession session, DateTime fromTime, DateTime toTime) { var ortoCriteria = DetachedCriteria.For<OrtoVisiteret>() .SetProjection(Projections.Distinct(Projections.Property<OrtoVisiteret>(x => x.Patient))) ;
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.