Để giải thích sự khác biệt giữa CreateCriteria và CreateAlias trong NHibernate 2.0 + cho phép xem mô hình miền sau.
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; }
}
Bây giờ nếu bạn viết tiêu chí sau để bên tham gia những tổ chức này
var criteria = DetachedCriteria.For<Product>()
.CreateCriteria("Category", JoinType.InnerJoin)
.CreateCriteria("ProductStocks", "ps", JoinType.InnerJoin)
.Add(Restrictions.Le("ps.Stock",10));
Các tiêu chí ở trên không làm việc, bởi vì khi CreateCriteria đầu tiên chạy nó trở về "Thể loại" thực thể, do đó khi CreateCriteria thứ hai thực hiện nó không tìm thấy thuộc tính ProductStocks trong thực thể "Danh mục" và truy vấn sẽ không thành công.
Vì vậy, cách chính xác để viết tiêu chí này là
var criteria = DetachedCriteria.For<Product>()
.CreateAlias("Category", "c", JoinType.InnerJoin)
.CreateCriteria("ProductStocks", "ps", JoinType.InnerJoin)
.Add(Restrictions.Le("ps.Stock",10));
Khi CreateAlias đầu tiên chạy nó trở về "sản phẩm" tổ chức nào, khi CreateCriteria thứ hai thực hiện nó sẽ tìm thấy ProductStocks bất động sản trong "sản phẩm" thực thể.
Vì vậy, TSQL sẽ như thế này.
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
Tôi hy vọng điều này sẽ hữu ích.
Nhưng bạn có thể chỉ định loại kết nối trong quá tải CreateAlias? CreateAlias luôn luôn dường như mặc định để tham gia bên trong cho tôi ... ngay cả khi nhiều người-một cho phép nulls. – dotjoe
Có với NH2 ++ CreateAlias cũng cho phép chỉ định một JoinType ghi đè các liên kết được ánh xạ. Tôi đoán rằng kể từ khi CreateCriteria trả về một đối tượng ICriteria ("rooted" tại thực thể liên quan), có thể tạo các truy vấn (nâng cao) khác nhau do ICriteria được tạo ra có thể được thao tác theo nhiều cách. – Jaguar