流畅的NHibernate:查询多对多关系

时间:2011-06-28 14:20:06

标签: c# linq fluent-nhibernate

我有这两个对象

public class Product {
  public virtual int Id { get; set; }
  public virtual string Name { get; set; }
  public virtual IEnumerable<Store> Stores { get; set; }
}

public class Store {
  public virtual int Id { get; set; }
  public virtual string Name { get; set; }
  public virtual IEnumerable<Product> Products { get; set; }
}

Fluent NHibernate为我创建了三个表,一个用于产品,一个用于商店,一个用于它们之间的关系。

如何编写一个查询来获取与某个产品无关的所有商店?

在商店资料库中,我可以执行以下操作:

return GetAll().Where(x => !x.Products.Any(y => y.Id == productId));

......但这看起来效率不高。

我尝试过以下一行:

return Session.QueryOver<Store>().Where(x => !x.Products.Any(y => y.Id == productId)).List();

...但似乎FH无法查询不属于查询对象的属性(产品ID不在公司表中等)。

2 个答案:

答案 0 :(得分:1)

试试这个:

return Session.QueryOver<Store>().Where(x => x.Products.Where(y => y.Id == productId).Count() == 0).List();

答案 1 :(得分:0)

这是一个可能的解决方案,假设您有一个comboBox,您可以在其中选择一个产品,并且您想要一个无法找到该产品的商店列表,解决方案如下:

Product product = session.Query<Product>()
                    .Where(x => x.Id == ((Product)comboBoxProduct.SelectedItem).Id)
                    .SingleOrDefault();

IList<Store> stores = session.QueryOver<Store>()
                    .Right.JoinQueryOver<Product>(x => x.ProductsInStores)
                    .Where(y => y.Id != product.Id)
                    .List<Store>();

注意:“ProductsInStores”将是连接“Product”和“Store”的第三个类

您还应在产品和商店地图中声明此第三类的名称。

在产品映射中,您应该:

HasManyToMany(x => x.Stores)
            .Cascade.All()
            .Table("ProductsInStores");

在商店映射中,您应该:

HasManyToMany(x => x.Products)
            .Cascade.All()
            .Inverse()
            .Table("ProductsInStores");