Reputation: 621
I am having a lot of difficulty figuring out how to perform a query on 2 tables that don't have reference to each other in code, for example, I have
Customer -> Product* where customer and product have reference to each other
and Inventory -> Product* where product does not have reference to Inventory
I would like to find all customer who dont have their product in inventory.
I have done this so far
var subQueryInv= DetachedCriteria.For<Inventory>();
subQueryInv
.Add(Restrictions.IsNotNull("Product.Id"))
.SetProjection(Projections.Property<Inventory>(inv=> inv.Product.Id));
var subQueryProd = DetachedCriteria.For<Product>();
subQueryTire
.Add(Subqueries.PropertyNotIn("Id", subQueryInv))
.SetProjection(Projections.Property<Tire>(prod=> prod.Customer.Id));
var subQueryCust= DetachedCriteria.For<Customer>();
subQueryCust
.Add(Subqueries.PropertyIn("Id", subQueryProd))
.SetProjection(Projections.Property<TireSet>(cust => cust.Id));
That works, bt the query is very innefficient, it is generating SQL like this for the Inventory part ...WHERE Product.Id NOT IN (SELECT Inventory.ProductId FROM Inventory WHERE Inventory.ProductId IS NOT NULL)
So for each product record, it is querying the entire Inventory table. How can I get the subquery to have a reference to the parent Id like this:
...WHERE Product.Id NOT IN (SELECT Inventory.ProductId FROM Inventory WHERE Inventory.ProductId IS NOT NULL AND Inventory.ProductId = Product.Id)
?
Upvotes: 1
Views: 1275
Reputation: 30803
you can use an alias to reference the main criteria
var subQueryInv= DetachedCriteria.For<Inventory>();
.Add(Restrictions.IsNotNull("Product.Id"))
.Add(Restrictions.PropertyEq("Product", "product"))
.SetProjection(Projections.Property<Inventory>(inv => inv.Product.Id));
var subQueryProd = DetachedCriteria.For<Product>("product");
Upvotes: 2