2015-12-29 21 views
0

我想我只是在尋找錯誤的術語,因爲我似乎無法找到答案,我相當肯定是一個簡單的問題。使用NHibernate標準檢索導航屬性

我有兩個類/映射(簡化);

public class Applications 
{ 
    public int Id {get; set;} 
    public string Name {get; set;} 
    public ApplicationType {get; set;} 
    public IEnumerable<ApplicationProperty> ApplicationProperties {get; set;} 
} 

public class ApplicationProperties 
{ 
    public int Id {get; set;} 
    public int Application_Id {get; set} 
    public string Value {get; set;} 
} 

我試圖建立一個標準類(可能誤導)試圖讓我們的代碼更易讀/可重複使用,如下:

public static class ApplicationsQuery 
{ 
    public static ICriteria GetQuery(ISession session) 
    { 
     return session.CreateCriteria(typeof(Application)); 
    } 

    public static ICriteria WithType(this ICriteria crit, ApplicationType type) 
    { 
     crit.Add(
      Restrictions.Eq(
       Projections.ProjectionList().Add(
        Projections.Property<Application>(a => a.ApplicationType)), type)); 
     return crit; 
    } 

    public static ICriteria WithProperties(this ICriteria crit) 
    { 
     // What goes here?! 
    } 
} 

所以,我可以這樣做

ICriteria query = ApplicationsQuery.GetQuery(session).WithType(ApplicationType.GameServer).WithProperties(); 

我已經嘗試了各種東西,如;

DetachedCriteria properties = 
      DetachedCriteria.For<Application>() 
       .SetProjection(Projections.Property<Application>(a => a.ApplicationProperties)); 
return crit.Add(Subqueries.Select(properties)); 
// Or this 
return crit.SetFetchMode("ApplicationProperties", FetchMode.Eager); 

但我無法得到填充的ApplicationProperties。
我的測試設置看起來像這樣;

session.Save(new Application("Test Application 1", ApplicationType.GameServer), 1); 
session.Save(new Application("Test Application 2", ApplicationType.Manager), , 2); 
session.Save(new ApplicationProperty(1, "Test Property"), 1); 

編輯 添加的映射關係給我的感覺,有可能與他們的問題。

public class ApplicationMapping : ClassMap<Application> 
{ 
    public ApplicationMapping() 
    { 
     Table("Applications"); 
     Id(o => o.Id, "Application_Id").GeneratedBy.Assigned(); 
     Map(o => o.Name).Column("Logical_Name"); 
     Map(o => o.ApplicationType).Column("Application_Type").CustomType<ApplicationType>(); 

     HasMany(o => o.ApplicationProperties).KeyColumn("Application_Id").ReadOnly().Cascase.None(); 
    } 
} 

public class ApplicationPropertyMapping : ClassMap<ApplicationProperty> 
{ 
    public ApplicationPropertyMapping() 
    { 
     Table("Application_Properties"); 
     Id(o => o.Id).GeneratedBy.Identity().Column("Property_Id"); 
     Map(o => o.ApplicationId).Column("Application_Id"); 
     Map(o => o.Value).Column("Property_Value"); 
    } 
} 

回答

0

更新:我剝離下來的代碼

public class ApplicationsQueryBuilder 
{ 
    private static readonly IProjection ApplicationTypeProperty = Projections.Property<Application>(a => a.ApplicationType); 

    private readonly DetachedCriteria _query = DetachedCriteria.For<Application>(); 
    private bool _withProperties; 
    private bool _filteredByCollection; 

    public ApplicationsQueryBuilder WithType(ApplicationType type) 
    { 
     _query.Add(Restrictions.Eq(ApplicationTypeProperty, type)); 
     return this; 
    } 

    public ApplicationsQueryBuilder WithTypes(params ApplicationType[] types) 
    { 
     var or = Restrictions.Disjunction(); 
     foreach (var type in types) 
     { 
      or.Add(Restrictions.Eq(ApplicationTypeProperty, type)); 
     } 

     _query.Add(or); 
     return this; 
    } 

    public ApplicationsQueryBuilder WithProperties() 
    { 
     _withProperties = true; 
     return this; 
    } 

    public ApplicationsQueryBuilder WithProperty(string name) 
    { 
     _query.CreateCriteria("ApplicationProperties") 
      .Add(Restrictions.Eq("Name", name)); 
     _filteredByCollection = true; 
     return this; 
    } 
    ... 

    public ICriteria Create(ISession session) 
    { 
     if (_withProperties && _filteredByCollection) 
     { 
      _query.SetProjection(Projections.Id()); 
      return session.CreateCriteria<Application>() 
       .SetFetchMode("ApplicationProperties", FetchMode.Eager); 
       .Add(Subqueries.PropertyIn("Id", _query)); 
     } 
     else if (_withProperties) 
     { 
      return _query.GetExecutableCriteria(_session) 
       .SetFetchMode("ApplicationProperties", FetchMode.Eager); 
     } 
     else 
     { 
      return _query.GetExecutableCriteria(session); 
     } 
    } 
} 
+0

我不認爲這個'公共IEnumerable的 ApplicationProperties {獲得;私人設置;}'是有效的。 'ApplicationProperties'是一個引用/導航屬性,它應該是整個對象,而不僅僅是一個字符串。 – Trent

+0

你真的需要一個完整的對象嗎?它看起來像一個簡單的字符串,NHibernate支持。告訴我,如果你需要幫助映射它 – Firo

+0

是的,我簡化了一些。它在技術上是4個字符串; Name,Value,ExtendedValue1和ExtendedValue2(所有字符串)。我已經將映射關閉了,我可以創建一個查詢來引入'ApplicationProperties',問題是試圖將'Application'和它的所有'ApplicationProperties'一起拉入。 – Trent