Pour expliquer la différence entre CreateCriteria et CreateAlias dans NHibernate 2.0 + permet de voir le modèle de domaine suivant.
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; }
}
Maintenant, si vous écrivez des critères suivants à jointure interne ces entités
var criteria = DetachedCriteria.For<Product>()
.CreateCriteria("Category", JoinType.InnerJoin)
.CreateCriteria("ProductStocks", "ps", JoinType.InnerJoin)
.Add(Restrictions.Le("ps.Stock",10));
Les critères ci-dessus ne vais pas travailler parce que quand la première createCriteria exécute retour entité « Catégorie », donc lorsque le second createCriteria l'exécuter ne trouvera pas la propriété ProductStocks dans l'entité "Category" et la requête échouera.
Ainsi, la manière correcte d'écrire ce critère est
var criteria = DetachedCriteria.For<Product>()
.CreateAlias("Category", "c", JoinType.InnerJoin)
.CreateCriteria("ProductStocks", "ps", JoinType.InnerJoin)
.Add(Restrictions.Le("ps.Stock",10));
Lorsque les premiers createAlias l'exécute retour entité « produit », lorsque le second createCriteria exécutent il trouvera ProductStocks de propriété dans l'entité « produit ».
Donc le TSQL sera comme ça.
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
J'espère que cela aidera.
Mais vous pouvez spécifier le type de jointure dans la surcharge CreateAlias? CreateAlias semble toujours utiliser par défaut la jointure interne pour moi ... même lorsque le multiple-to-one autorise les valeurs nulles. – dotjoe
Oui avec NH2 ++ le CreateAlias permet également de spécifier un JoinType remplaçant les associations mappées. Je suppose que puisque le CreateCriteria renvoie un objet ICriteria ("rooted" à l'entité associée) il peut être possible de générer des requêtes différentes (avancées) puisque les ICriteria générées peuvent être manipulées de plusieurs manières. – Jaguar