Aby wyjaśnić różnicę między CreateCriteria i CreateAlias w NHibernate 2.0 + pozwala zobaczyć następujący model domeny.
public class Product
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual decimal Price { get; set; }
public virtual Category Category { get; set; }
public virtual IList<ProductStock> ProductStocks { get; set; }
}
public class Category
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public virtual IList<Product> Products { get; set; }
}
public class ProductStock
{
public virtual int Id { get; private set; }
public virtual Product Product { get; set; }
public virtual string WarehouseName { get; set; }
public virtual int Stock { get; set; }
}
Teraz jeśli piszesz następujące kryteria do sprzężenia wewnętrznego tych podmiotów
var criteria = DetachedCriteria.For<Product>()
.CreateCriteria("Category", JoinType.InnerJoin)
.CreateCriteria("ProductStocks", "ps", JoinType.InnerJoin)
.Add(Restrictions.Le("ps.Stock",10));
Powyższe kryteria nie będzie działać, bo gdy pierwszy CreateCriteria prowadzi to return „Kategoria” podmiot, zatem gdy drugie CreateCriteria go wykonać nie znajdę właściwości ProductStocks w encji "Category", a zapytanie nie powiedzie się.
więc poprawny sposób napisać powyższe kryteria jest
var criteria = DetachedCriteria.For<Product>()
.CreateAlias("Category", "c", JoinType.InnerJoin)
.CreateCriteria("ProductStocks", "ps", JoinType.InnerJoin)
.Add(Restrictions.Le("ps.Stock",10));
Po pierwsze CreateAlias przebiega powrót „Produkt” podmiot, gdy drugie CreateCriteria wykonać znajdzie ProductStocks własności w „produkt” podmiotu.
Tak więc TSQL będzie taki.
SELECT this_.ProductID as ProductID8_2_,
this_.Name as Name8_2_,
this_.Price as Price8_2_,
this_.CategoryID as CategoryID8_2_,
ps2_.ProductStockID as ProductS1_9_0_,
ps2_.Stock as Stock9_0_,
ps2_.ProductID as ProductID9_0_,
ps2_.WarehouseID as Warehous4_9_0_,
c1_.CategoryID as CategoryID0_1_,
c1_.Name as Name0_1_
FROM [Product] this_
inner join [ProductStock] ps2_ on this_.ProductID = ps2_.ProductID
inner join [Category] c1_ on this_.CategoryID = c1_.CategoryID
WHERE ps2_.Stock <= 10
Mam nadzieję, że to pomoże.
Ale można określić typ łączenia w Przeciążenie CreateAlias? CreateAlias zawsze wydaje się domyślnym łączeniem wewnętrznym dla mnie ... nawet gdy wiele do jednego dopuszcza wartości zerowe. – dotjoe
Tak, z NH2 ++ funkcja CreateAlias pozwala również określić typ JoinType nadpisujący skojarzenia mapowane. Zgaduję, że ponieważ CreateCriteria zwraca obiekt ICriteria ("rooted" w powiązanej encji) może być możliwe generowanie różnych (zaawansowanych) zapytań, ponieważ wygenerowane ICriteria mogą być manipulowane na wiele sposobów. – Jaguar