2011-11-16 75 views
0

我有以下的(非常簡化的)域:查詢NHibernate的屬性與LINQ

public class Product 
{ 
    public virtual int Id { get; set; } 
    public virtual string Description { get; set; } 
    public virtual IList<Category> Categories { get; set; } 
} 

public class Category 
{ 
    public virtual int Id { get; set; } 
    public virtual string Description { get; set; } 
} 

許多一對多收集使用下面的XML映射:

<bag name="Categories" table="ProductsCategories"> 
    <key column="ProductID" /> 
    <many-to-many column="CategoryID" class="Category" /> 
</bag> 

當我'使用產品屬性加載我的類別全部工作正常:

Product product = ProductRepository.Find(1); 
var categories = product.Categories; 

的問題是,當我嘗試過濾我的收藏,比如:

Product product = ProductRepository.Find(1); 
var categories = product.Categories.Where(c => c.SomeProperty == someValue); 

查詢是對數據庫執行,但它使用LINQ到對象篩選的結果!是否有可能在不使用HQL的情況下解決這個問題,也不需要映射一個名爲「OrderDetail」的新實體?

+0

這不是一個有效的答案,但如果你做它的工作原理:VAR類= product.Categories.ToList()將(C => c.SomeProperty == someValue中); – 4imble

+0

是的,但NHibernate會從數據庫加載整個集合,然後它將使用LINQ to Objects來執行過濾器。 – StockBreak

+0

你的repository.Find(#)方法是什麼樣的? – 4imble

回答

0

的問題是,Categories被聲明爲

IList<Category> Categories 

這意味着您的查詢將使用Enumerable.Where代替Queryable.Where

我期望NHibernate的支持實現IQuerable<T>,你會用它來聲明你的財產,例如,另一個接口

public virtual IQueryableList<Category> Categories { get; set; } 

我沒有使用過NHibernate的在憤怒,所以我不知道是什麼類型實際上是,但是這就是你應該尋找。

+0

謝謝你的回答。問題是我不想將我的屬性公開爲IQueryable。我應該真的這樣做嗎? – StockBreak

+0

@StockBreak:如果你*不*暴露'IQueryable ',你如何期望查詢被翻譯成SQL? –

+0

我想避免公開一個IQueryable屬性,因爲我總是隱藏存儲庫方法中的LINQ操作,然後簡單地返回IList或IEnumerable屬性。我剛剛嘗試過這一點,並加載訂單時出現錯誤:_無法投射'NHibernate.Collection.Generic.PersistentGenericBag'1 [MyDomain.Entities.OrderDetail]類型的對象來鍵入'System.Linq.IQueryable'1 [MyDomain .Entities.OrderDetail]'_。 – StockBreak

1

您需要查詢category,而不是product的類別。 (你可以用你最初想要的ISession.Filter來做你想做的事情,但是我上次看到LINQ並不需要)。

例如

from category in session.Linq<Category> 
where category.Products.Contains(product) and category.SomeProperty == someValue 
select category 
+0

嗨大衛,不幸的是我的關係是多對多而不是一對多。我的'Category'對象沒有'Product'屬性。 – StockBreak

+0

@StockBreak - 我更改了查詢以將'Contains'用於'Category.Products'屬性。如果Category沒有'Products'屬性,那麼添加一個懶加載的屬性。 –

+0

不幸的是,這不起作用,因爲'category.Products'將被首先評估,然後'包含(產品)'將被執行LINQ to Objects。 – StockBreak