使用NHibernate标准检索导航属性

时间:2015-12-29 06:09:17

标签: c# nhibernate fluent-nhibernate nhibernate-criteria

我认为我只是在寻找错误的条款,因为我似乎无法找到答案,我相当确定这是一个简单的问题。

我有两个类/映射(简化);

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

我尝试过各种各样的事情,例如;

 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");
    }
}

1 个答案:

答案 0 :(得分: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);
        }
    }
}