我正在尝试为具有复合键的表设置映射,但我只对其中一个键列中具有固定值的值感兴趣。例子:
第一 | 第二个 | 价值 |
---|---|---|
100 | 1 | 42 |
100 | 2 | 42 |
目标是在
Entity
类中只有 First 和 Value 属性。
我尝试用
where
子句映射表:
<class name="Entity" table="table" where="second = 1">
<id name="First" column="first" />
<property name="Value" column="value" />
</class>
此配置适用于获取和更新,但当我尝试使用“无法将 NULL 插入 SECOND”插入新值时,它会崩溃。我希望 NHibernate 能够解析
where
子句并向所有 insert
SQL 添加“1”。
有没有办法为要添加到生成的
insert
语句的列设置静态值?
更新: 我设法使
inserts
与映射到准只读属性的 composite-id
一起工作,但这感觉像是一个非常肮脏的解决方案:
<class name="Entity" table="table" where="second = 1">
<composite-id>
<key-property name="First" column="first" />
<key-property name="Second" column="second" />
</composite-id>
<property name="Value" column="value" />
</class>
C#:
public class Entity
{
public int First { get; set; }
public int Second { get { return 1; } set { } }
public int Value { get; set; }
}
有可能属性只存在于实体模型中。因为 Id 在数据库中是复合的,所以它必须这样映射才能唯一。
public class MyClassMap : ClassMap<MyClass>
{
public MyClassMap()
{
CompositeId()
.Property(x => x.First)
.Property(x => this.Second).Access.Using<StaticValueAccessor>();
}
public long Second { get; set; }
}
class StaticValueAccessor : IPropertyAccessor, IGetter, ISetter
{
private static readonly IDictionary<string, object> _staticValues = new Dictionary<string, object>
{
{ nameof(MyClass) + "." + nameof(MyClass.Second) }
};
public bool CanAccessThroughReflectionOptimizer => false;
public Type ReturnType { get; private set; }
public string PropertyName { get; private set; }
public MethodInfo Method => throw new NotImplementedException();
public object Get(object target)
{
return _staticValues[target.GetType().Name + "." + PropertyName];
}
public object GetForInsert(object owner, IDictionary mergeMap, ISessionImplementor session) => Get(owner);
public IGetter GetGetter(Type theClass, string propertyName)
{
PropertyName = propertyName;
ReturnType = _staticValues[theClass + "." + propertyName].GetType();
return this;
}
public ISetter GetSetter(Type theClass, string propertyName)
{
PropertyName = propertyName;
return this;
}
public void Set(object target, object value) { }
}
和查询
session.Get<MyClass>(new MyClass { First = 123 });
或者,您可以首先为 id 创建一个类,然后使用访问器在那里添加一个不可见的属性。