QueryOver使用被忽略的属性

本文关键字:属性 QueryOver | 更新日期: 2023-09-27 18:21:38

我有两个实体:

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

如何检索具有特定Parent Id的Child对象集?

QueryOver使用被忽略的属性

未测试,但您可以尝试以下操作:

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

您将无法在任何NHibernate查询中查询未映射的关联,但这至少可以最大限度地减少编译时检查的损失。

据我所知,这在一定程度上是有限的。{alias}将始终被实体的别名所替换,这意味着如果您想对不以Child开头的更复杂的查询执行此操作,您可能会运气不佳。

我使用CreateSQLQuery而不是QueryOver:解决了这个问题

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

如果可能的话,我想看看更好的方法,失去编译时检查有点令人沮丧。