QueryOver使用被忽略的属性

时间:2014-09-12 17:55:50

标签: c# nhibernate fluent-nhibernate 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);
    }
}

现在,如果我想查询给定父ID的所有Child个对象,我会执行此操作:

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

然而,这会引发QueryException

  

无法解析属性:ParentId:My.Namespace.Child

如何检索具有特定Child ID的Parent个对象?

2 个答案:

答案 0 :(得分:2)

未经测试,但你可以试试这个:

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

您无法在任何NHibernate查询中查询未映射的关联,但这至少可以减少编译时检查的丢失。

这与我所说的有些限制。 {alias}将始终替换为 root 实体的别名,这意味着如果您要对不以Child开头的更复杂的查询执行此操作,则可能运气不好。

答案 1 :(得分:0)

我使用CreateSQLQuery代替QueryOver解决了问题:

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

如果可能的话,我希望看到更好的方法,失去编译时检查是一种挫折。