映射 HasMany 关系,无需任何键列 - 仅Where()

问题描述 投票:0回答:1

从概念上讲,我想映射这样的集合:

HasMany(x => x.Children).Where("some_column_name='foo'");

HasMany() 的默认模式要求我提供一个 KeyColumn,它应该存在于子表中,并且其值应该是父表的标识符值。但是,我不想那样做。我想为连接到这个子表关系提供唯一且完整的sql子句。

可以吗?

我尝试完全从映射中删除 KeyColumn。但是,nHibernate 默认情况下会在生成的 sql 中添加一些内容——它似乎是父类的某种标识符占位符。例如,如果此关系的父类称为“Parent”,则 nH 会生成如下 SQL

从孩子中选择....child0_where([我的自定义where子句,耶])和child0_.Parent_id=?

我希望它停止向此连接添加任何附加子句,并仅使用映射的 .Where() 方法提供的自定义 where 子句。

nhibernate fluent-nhibernate
1个回答
0
投票

我不知道确切的情况,所以可能有一个更简单的解决方案,但这应该可行。

使用的课程

class Parent : Entity
{
    public virtual IList<Child> Children { get; protected set; } = new List<Child>();
}

class Child : Entity
{
    public virtual string ChildType { get; set; }
}

映射

class ParentMap : ClassMap<Parent>
{
    public ParentMap()
    {
        Id(x => x.Id);

        HasMany(x => x.Children)
            .PropertyRef(nameof(ChildType))
            .KeyColumn("ChildType")
            .Cascade.All();

        Map(x => ChildType).Access.Using<ChildTypeGetter>();
    }

    public string ChildType { get; set; }
}

class ChildTypeGetter : IPropertyAccessor, IGetter, ISetter
{
    public IGetter GetGetter(Type theClass, string propertyName) => this;
    public ISetter GetSetter(Type theClass, string propertyName) => this;

    public bool CanAccessThroughReflectionOptimizer => false;
    public string PropertyName => nameof(ParentMap.ChildType);
    public Type ReturnType => typeof(string);
    public MethodInfo Method => throw new NotImplementedException();

    public object Get(object target) => "foo";
    public object GetForInsert(object owner, IDictionary mergeMap, ISessionImplementor session) => Get(owner);
    public void Set(object target, object value) { }
}

class ChildMap : ClassMap<Child>
{
    public ChildMap()
    {
        Id(x => x.Id);

        Map(x => x.ChildType);
    }
}

测试代码

session.Save(new Child { ChildType = "foo" });
session.Save(new Child { ChildType = "foo" });
session.Save(new Child { ChildType = "bar" });
var parentId = session.Save(new Parent());
session.Flush();
session.Clear();

var parent = session.Get<Parent>(parentId);

Assert.Equal(2, parent.Children.Count);
© www.soinside.com 2019 - 2024. All rights reserved.