I think I'm just searching for the wrong terms, since I can't seem to find an answer to what I'm fairly sure is a simple question.
I have two classes/mappings (simplified);
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;}
}
I'm trying to build up a Criteria class in a (possibly misguided) attempt to make our code more readable/reusable, as follows;
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?!
}
}
So that I can do something like
ICriteria query = ApplicationsQuery.GetQuery(session).WithType(ApplicationType.GameServer).WithProperties();
I've tried various things such as;
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);
But I'm unable to get the ApplicationProperties to be populated.
My test setup looks like this;
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 Adding in the mappings as I get the feeling that there might be an issue with them.
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");
}
}
Update: i stripped down the code
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);
}
}
}