2014-09-12 103 views
2

我有兩個實體:QueryOver使用忽略屬性

public class Parent 
{ 
    public virtual int Id { get; set; } 
} 

public class Child 
{ 
    public virtual int Id { get; set; } 
    public virtual int ParentId 
    { 
     get 
     { 
      if (Parent != null) 
       return Parent.Id; 
      return -1; 
     } 

     set 
     { 
      if (Parent != null) 
       Parent = new Parent(); 
      Parent.Id = value; 
     } 
    } 

    protected virtual Parent Parent 
    { 
     get; 
     set; 
    } 
} 

Parent屬性設置像這樣簡化API的一面,我不想改變它公開揭露這個屬性。我有映射的重寫爲Child類,以適應這一點:

public class ChildMappingOverrides : IAutoMappingOverride<Child> 
{ 
    public void Override(AutoMapping<Child> mapping) 
    { 
     mapping.References<Parent>(Reveal.Member<Child>("Parent")).Column("Parent_id"); 
     mapping.IgnoreProperty(x => x.ParentId); 
    } 
} 

現在,如果我想查詢所有Child對象對於一個給定父ID,我會執行此:

session.QueryOver<Child>().Where(c => c.ParentId == 1); 

然而,這將引發一個QueryException

無法解析屬性:的的ParentId:My.Namespace.Child

如何檢索具有特定Parent ID的一組Child對象?

回答

2

未經檢驗的,但你可以試試這個:

session.QueryOver<Child>() 
    .Where(Restrictions.Eq(
     Projections.SqlProjection(
      "{alias}.Parent_id as ParentId", 
      new[] { "ParentId" }, 
      new[] { NHibernateUtil.Int32 }), 1)) 
    .List<Child>(); 

你不會要能夠在任何NHibernate的查詢上映射的關聯查詢,但這次至少最大限度地減少編譯時檢查的損失。

這與我所能說的有些有限。 {alias}將始終替換爲實體的別名,這意味着如果您希望對不是以Child開頭的更復雜的查詢執行此操作,那麼您可能會失敗。

+0

我更喜歡這個:)謝謝安德魯,它與我做的一個小小的調整,只是爲了匹配我的例子中的列名稱。 – 2014-09-12 19:31:50

+0

@PatrickQuirk:沒問題 - 我希望有一種更堅實的方式來做你以後的事情 – 2014-09-12 19:32:29

0

我用CreateSQLQuery代替QueryOver解決它:

session.CreateSQLQuery("SELECT C.* FROM CHILD C WHERE C.Parent_id = (:id)") 
     .AddEntity(typeof(Child)) 
     .SetInt32("id", parentId) 
     .List<Child>(); 

我想看到一個更好的方式,如果可能的話,失去編譯時檢查是一種令人沮喪的。