0

我正在尝试在 NHibernate 中为以下语句创建标准:

SELECT *
  FROM InventoryItems
  where id not in (select inventory_id from InventoryItemCategories where Category_Id = 'EB0DA6DE-DC18-4306-9EF7-E506463555A9')

或者我认为这个更好

SELECT *
  FROM InventoryItems
  where id not exists (select inventory_id from InventoryItemCategories where Category_Id = 'EB0DA6DE-DC18-4306-9EF7-E506463555A9')

我已经尝试过了,但它不起作用:

 var criteria = Session.CreateCriteria<InventoryItem>()
      .Add(Subqueries.WhereNotExists(("id"), DetachedCriteria.For<InventoryItemCategories>()
       .Add(Restrictions.Eq("Category_id",inventoryCategoryId))));

非常感谢您的帮助

4

4 回答 4

1

如果你把你的两个实体联系起来,它会更容易

public class InventoryItem
{
    public virtual object Id{get;set;}
    public virtual IList<InventoryItemCategory> InventoryItemCategories{get;set;}
}
public class InventoryItemCategoriy
{
    public virtual InventoryItem InventoryItem{get;set;}
}
public class InventoryItemMap : ClassMap<InventoryItem>
{
    public InventoryItem()
    {
        Id(x=>x.Id);
        HasMany(x=>x.InventoryItemCategories).KeyColumn("Inventory_id");
    }
}
public class InventoryItemCategoryMap:ClassMap<InventoryItemCategory>
{
    public InventoryItemCategory()
    {
        References(x=>x.InventoryItem).Column("Id");
    }
}

您的查询如下

session.Query<InventoryItem>().Where(x=>!x.InventoryItemCategories.Any(c=>c.Id=="EB0DA6DE-DC18-4306-9EF7-E506463555A9")).ToList();
于 2013-11-05T19:57:19.730 回答
0

您可以使用子查询或非限制,例如:

var subqueryFoodsWithCancerogenousSubstances = 
    DetachedCriteria.For(typeof(FoodCancerSubst))
            .SetProjection(Projections.Property("FoodId"));

ICriteria noCancerFood =
    session.CreateCriteria(typeof(Food))
    .Add(Subqueries.NotIn(subqueryFoodsWithCancerogenousSubstances))
    // check ID, else use PropertyNotIn(...)

或者当对没有 NotIn 的分离值列表使用 IN 子句时:

    .Add(Restrictions.Not(Restrictions.In("Id", cancerogenousFoodIdsList)))
于 2013-11-05T19:44:48.670 回答
0

你不能这样做吗:

criteria.Add(Restrictions.Not(Restrictions.In ("id", detachedCrit));
于 2013-11-05T19:45:35.560 回答
-1

IN通常会映射到一个Contains调用,您只需在其中反转参数:

var subquery = context.InventoryItemCategories
    .Where(category => category.Category_Id == 
        'EB0DA6DE-DC18-4306-9EF7-E506463555A9')
    .Select(category => category.inventory_id);

var query = context.InventoryItems.Where(item => !subquery.Contains(item.id));
于 2013-11-05T18:28:49.253 回答