将数据库列映射到常量值,而不需要实体类中的属性 [英] Map database column to constant value without the need for a property in the entity class

查看:102
本文介绍了将数据库列映射到常量值,而不需要实体类中的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以将数据库列映射到一个常量值而不需要实体类中的属性?这基本上是对数据库中该列缺少缺省值的一种解决方法,与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆