【问题标题】:NHibernate - IUserType For Changing Type?NHibernate - IUserType 用于更改类型?
【发布时间】:2012-02-28 16:31:54
【问题描述】:

我的应用程序有以下类:

public class Widget {        
    public virtual int Id { get; set; }
    public virtual WidgetType Type { get; set; }
    public virtual string Parameters { get; set; }
}

public class WidgetType {        
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string ParametersAssembly { get; set; }
    public virtual string ParametersClass { get; set; }
}

现在,如果我想更新特定小部件的参数,我会说:

// Get the widget
var widget = GetWidget(1);

// Create an instance of the type parameters class
var parameters = Activator.CreateInstance(Assembly.LoadFrom(Server.MapPath("~/bin/"
    + widget.Type.ParametersAssembly + ".dll")).GetType(widget.Type.ParametersClass));

... Code here to update the parameters

widget.Parameters = new XmlSerializer(parameters.GetType()).Serialize(parameters);

当我想获得参数时,我必须做相反的事情。你可以想象这变得相当乏味。我想知道是否可能自动执行此操作?

我一直在研究 IUserType 接口。我找到了一个类似的article。但是我的问题有点复杂,因为我的类型会根据小部件的类型而变化。

如果有人能告诉我这是否可行以及如何实现,我将不胜感激。谢谢

【问题讨论】:

    标签: nhibernate nhibernate-mapping iusertype


    【解决方案1】:

    简单的方法

    public class Widget
    {
        public virtual int Id { get; set; }
        public virtual WidgetType Type { get; set; }
    
        private string _serializedParameters;
        private virtual string SerializedParameters {
            get
            {
                return new XmlSerializer(Parameters.GetType()).Serialize(Parameters);
            }
            set
            {
                _serializedParameters = value;
                // code to deserialize the Parameters and set to Parameters
                var ptype = Assembly.LoadFrom(Server.MapPath("~/bin/" + widget.Type.ParametersAssembly + ".dll")).GetType(widget.Type.ParametersClass);
                Parameters = Activator.CreateInstance(ptype);
            }
        }
        private object _parameters;
        public virtual object Parameters
        {
            get
            {
                if (_parameters == null)
                    _parameters = Activator.CreateInstance(Assembly.LoadFrom(Server.MapPath("~/bin/" + widget.Type.ParametersAssembly + ".dll")).GetType(widget.Type.ParametersClass));
                return _parameters;
            }
            set { _parameters = value; }
        }
    }
    

    它不能在Parameters 属性中,因为你必须使用get -> alter -> set 而不是get -> alter。但是你是对的,构建参数对象应该进入参数的获取器,因为只有在那里我们才能确保加载 WidgetType

    它本质上与 UserType 相同,只是我们知道 WidgetType 存在

    【讨论】:

    • 谢谢,我可以看到这个工作,但我不确定我是否完全理解它。参数属性是映射到数据库的属性吗?如果是这样,那么它不应该是一个字符串并且 SerializedParameters 会返回一个对象吗?
    • SerializedParameters 是映射到 db 的属性。它包含需要其他属性才能工作的转换,因此在其他属性可能未初始化的 UserType 中更难进行。 Parameters 根本没有映射
    • 仍然没有太多的快乐。很抱歉让您感到痛苦,但您确定序列化和反序列化代码位于 SerializedParameters 属性而不是 Parameters 属性中吗?如果您能提供一个根据我的场景获取和设置属性的示例,那将不胜感激。谢谢
    • 感谢您的修改。它帮助很大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    相关资源
    最近更新 更多