将数据库列映射到常量值,而不需要实体类中的属性 [英] Map database column to constant value without the need for a property in the entity class
问题描述
是否可以将数据库列映射到一个常量值而不需要实体类中的属性?这基本上是对数据库中该列缺少缺省值的一种解决方法,与NOT NULL约束结合使用。该数据库是外部的,不能改变,但我不需要在该表中的所有列,因此不希望在我的实体类中有相应的属性。
Is it possible to map a database column to a constant value without the need for a property in the entity class? This basically is a workaround for a missing default value on that column in the database in combination with a NOT NULL constrained. The database is external and can't be changed but I don't need all of the columns in that table and thus don't want to have corresponding properties in my entity class.
我的问题基本上与这个Hibernate JIRA问题中所描述的相同。 p>
I am asking basically the same as described in this Hibernate JIRA issue.
推荐答案
我的实现与hival有相同的想法,但进一步发展。基础是IPropertyAccessor的实现。
My implementation takes the same idea as hival but goes a lot further. the basis is an implementation of IPropertyAccessor
/// <summary>
/// Defaultvalues für nicht (mehr) benötigte Spalten siehe
/// http://elegantcode.com/2009/07/13/using-nhibernate-for-legacy-databases/
/// </summary>
public abstract class DefaultValuesBase : IPropertyAccessor
{
public abstract IEnumerable<IGetter> DefaultValueGetters { get; }
public bool CanAccessThroughReflectionOptimizer
{
get { return false; }
}
public IGetter GetGetter(Type theClass, string propertyName)
{
return DefaultValueGetters.SingleOrDefault(getter => getter.PropertyName == propertyName);
}
public ISetter GetSetter(Type theClass, string propertyName)
{
return new NoopSetter();
}
}
// taken from the link
[Serializable]
public class DefaultValueGetter<T> : IGetter {...}
// ---- and the most tricky part ----
public static void DefaultValues<T>(this ClasslikeMapBase<T> map, DefaultValuesBase defaults)
{
DefaultValuesInternal<T>(map.Map, defaults);
}
public static void DefaultValues<T>(this CompositeElementPart<T> map, DefaultValuesBase defaults)
{
DefaultValuesInternal<T>(map.Map, defaults);
}
private static void DefaultValuesInternal<T>(
Func<Expression<Func<T, object>>, PropertyPart> mapFunction, DefaultValuesBase defaults)
{
var noopSetter = new NoopSetter();
var defaultsType = defaults.GetType();
foreach (var defaultgetter in defaults.DefaultValueGetters)
{
var parameter = Expression.Parameter(typeof(T), "x");
Expression body = Expression.Property(parameter,
new GetterSetterPropertyInfo(typeof(T), defaultgetter, noopSetter));
body = Expression.Convert(body, typeof(object));
var lambda = Expression.Lambda<Func<T, object>>(body, parameter);
mapFunction(lambda).Column(defaultgetter.PropertyName).Access.Using(defaultsType);
}
}
// GetterSetterPropertyInfo inherits PropertyInfo with important part
public override string Name
{
get { return m_getter.PropertyName; } // propertyName is the column in db
}
// and finally in SomeEntityMap
this.DefaultValues(new SomeEntityDefaults());
public class SomeEntityDefaults : DefaultValuesBase
{
public override IEnumerable<IGetter> DefaultValueGetters
{
get
{
return new [] {
new DefaultValueGetter<int>("someColumn", 1),
new DefaultValueGetter<string>("somestrColumn", "empty"),
};
}
}
}
这篇关于将数据库列映射到常量值,而不需要实体类中的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!