2015-12-29 2 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;} 
} 

Я пытаюсь создать класс Criteria в (возможно, ошибочное) попытки, чтобы сделать наш код более удобным для чтения/многоразовые, следующим образом;

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(); 

Я пробовал различные вещи, такие как;

Но я не могу получить заполнение 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); 

EDIT Добавление в отображениях, как я чувствую, что может быть проблема с ними.

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

Update: я урезанная код

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 {получить; private set;} '. 'ApplicationProperties' является ссылочным/навигационным свойством, и он должен быть целым объектом, а не только строкой. – Trent

+0

Вам действительно нужен целый объект? это выглядит как простая строка для меня, и NHibernate поддерживает это. Скажите мне, если вам нужна помощь в его картировании. – Firo

+0

Да, я немного упростил его. Это технически 4 строки; 'Name',' Value', 'ExtendedValue1' и' ExtendedValue2' (все строки). У меня плохое отображение, и я могу создать запрос, чтобы вытащить «ApplicationProperties», проблема заключается в попытке задействовать «Приложение» вместе со всеми его «ApplicationProperties». – Trent

Смежные вопросы