gpt4 book ai didi

c# - 将数据库列映射到常量值,而不需要实体类中的属性

转载 作者:太空狗 更新时间:2023-10-30 01:24:32 27 4
gpt4 key购买 nike

是否可以在不需要实体类中的属性的情况下将数据库列映射到常量值?这基本上是针对数据库中该列缺少默认值并结合 NOT NULL 约束的解决方法。数据库是外部的,无法更改,但我不需要该表中的所有列,因此不希望在我的实体类中具有相应的属性。

我问的和this Hibernate JIRA issue中描述的基本一样.

最佳答案

根据 Firos 的回答,我解决了这个问题。但是,我不太喜欢使用的语法以及我必须为每个实体的默认值创建一个新类这一事实。

我现在得到的语法是这样的:

mapping.ConstantValue(0).Column(@"client_id");
// or
mapping.ConstantValue(0, @"client_id");

我为它创建了以下扩展方法:

public static PropertyPart
ConstantValue<TType, TValue>(this ClasslikeMapBase<TType> map, TValue value)
{
var getter =
new ConstantValueGetter<TValue>(CreateUniqueMemberName(), value);
ConstantValueAccessor.RegisterGetter(typeof(TType), getter);

var propertyInfo =
new GetterSetterPropertyInfo(typeof(TType), typeof(TValue),
getter.PropertyName, getter.Method, null);

var parameter = Expression.Parameter(typeof(TType), "x");
Expression body = Expression.Property(parameter, propertyInfo);
body = Expression.Convert(body, , typeof(object));

var lambda = Expression.Lambda<Func<TType, object>>(body, parameter);

return map.Map(lambda).Access.Using<ConstantValueAccessor>();
}

public static PropertyPart
ConstantValue<TType, TValue>(this ClasslikeMapBase<TType> map,
TValue value, string column)
{
return map.ConstantValue(value).Column(column);
}

重要的区别是:

  1. 第一个扩展方法返回 PropertyPart并且必须与 Column 结合使用指定常量值应映射到哪一列的方法。因此,在执行扩展方法时,列名是未知的,需要我们自己创建一个。这是由 CreateUniqueMemberName 完成的:

    private static string CreateUniqueMemberName()
    {
    return "Dummy" + Guid.NewGuid().ToString("N");
    }
  2. 因为您只能将类型指定为访问策略而不是实例,所以我无法创建 IPropertyAccessor实现允许我简单地传递一个 IGetter构造函数中的实例。这就是ConstantValueAccessor.RegisterGetter(typeof(TType), getter);解决。 ConstantValueAccessor有一个静态的 getter 集合:

    internal class ConstantValueAccessor : IPropertyAccessor
    {
    private static readonly
    ConcurrentDictionary<Type, SynchronizedCollection<IGetter>> _getters =
    new ConcurrentDictionary<Type, SynchronizedCollection<IGetter>>();

    public static void RegisterGetter(Type type, IGetter getter)
    {
    var getters =
    _getters.GetOrAdd(type,
    t => new SynchronizedCollection<IGetter>());
    getters.Add(getter);
    }

    public IGetter GetGetter(Type theClass, string propertyName)
    {
    SynchronizedCollection<IGetter> getters;
    if (!_getters.TryGetValue(theClass, out getters))
    return null;
    return getters.SingleOrDefault(x => x.PropertyName == propertyName);
    }

    // ...
    }

执行ConstantValueGetter<T>与提供的链接中的相同。

因为实现 GetterSetterPropertyInfo 并没有那么有趣, here这是。一个重要的区别是,此实现不依赖于 (Fluent) NHibernate。

关于c# - 将数据库列映射到常量值,而不需要实体类中的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8993997/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com