Чтобы объяснить разницу между CreateCriteria и CreateAlias в NHibernate 2.0 +, давайте рассмотрим следующую модель домена.
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; }
}
Теперь, если вы напишете следующие критерии для внутреннего объединения этих сущностей
var criteria = DetachedCriteria.For<Product>()
.CreateCriteria("Category", JoinType.InnerJoin)
.CreateCriteria("ProductStocks", "ps", JoinType.InnerJoin)
.Add(Restrictions.Le("ps.Stock",10));
Приведенные выше критерии не будут работать, поскольку при первом запуске CreateCriteria он возвращает сущность «Category», поэтому при выполнении второго CreateCriteria он не найдет свойство ProductStocks в сущности «Category», и запрос не будет выполнен.
Таким образом, правильный способ написать этот критерий -
var criteria = DetachedCriteria.For<Product>()
.CreateAlias("Category", "c", JoinType.InnerJoin)
.CreateCriteria("ProductStocks", "ps", JoinType.InnerJoin)
.Add(Restrictions.Le("ps.Stock",10));
Когда первый CreateAlias запускает, он возвращает сущность «Product», а при втором выполнении CreateCriteria он находит свойство ProductStocks в сущности «Product».
Так что TSQL будет таким.
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
Надеюсь, это поможет.