MyGeneration模板生成NHibernate映射文件和关系(one-to-one,one-to-many,many-to-many)

 

MyGeneration的几个NHibernate模板功能已经很强,但还是存在些问题。例如:Guid主键支持不佳,代码不易修改,不支持中文注释等等。所以我决定自己来改写此模版。我把一部分通用的函数提取到自己定义的基类中,这样调试和修改都方便另外增加了一部分新功能。

NHibernate里面的关系写起来也很烦人,很容易出错,所以我写了另一个模版专门生成关系代码。只需要把生成的代码拷到映射类文件和.hbm.xml文件中就可以了。

下载
如果你兴趣自己写模版,或者使用中有问题可以查看强大的代码生成工具MyGeneration

使用中发现什么问题,或者是有什么好的意见建议请及时和我联系。十分感谢!

下载完成后把DDLLY.MyGenerationTemplate.dll拷贝到MyGeneration的安装路径。把模版文件拷贝到MyGeneration的安装路径下的Templates目录里面的NHibernate目录里。

生成映射文件

运行MyGeneration,选择Edit里面的Default Settings...,进行适当的配置。如图

在Template Browser里面的NHibernate找到"DDL NHibernate Object Mapping"。运行此模版

输出路径表示生成模版的生成路径。启用nullable类型表示在.Net2.0中使用nullable类型,如果。

提示:你可以按住Ctrl或者Shift选择多个表。

Save按钮可以把的你设置存储在注册表中,下次将自动获得保存的设置。

选中你需要生成映射类的表,点Ok按钮。将生成映射文件。你可以在输出路径中找到他们。

下面是我生成的文件

/**//*
/*NHibernate映射代码模板
/*作者:DDL
/*版本更新和支持:http://renrenqq.cnblogs.com/
/*日期:2006年8月14日 
*/
using System;
 
namespace MyNamePlace
{
    /**//// <summary>
    ///    
    /// </summary>
    [Serializable]
    public sealed class User
    {
        私有成员#region 私有成员
            
        private bool m_IsChanged;
        private bool m_IsDeleted;
        private int m_UserId; 
        private string m_UserName; 
        private string m_Password; 
        private string m_Email;         
 
        #endregion
        
        默认( 空 ) 构造函数#region 默认( 空 ) 构造函数
        /**//// <summary>
        /// 默认构造函数
        /// </summary>
        public User()
        {
            m_UserId = 0; 
            m_UserName = null; 
            m_Password = null; 
            m_Email = null; 
        }
        #endregion
        
        公有属性#region 公有属性
            
        /**//// <summary>
        /// 
        /// </summary>        
        public  int UserId
        {
            get { return m_UserId; }
            set { m_IsChanged |= (m_UserId != value); m_UserId = value; }
        }
            
        /**//// <summary>
        /// 
        /// </summary>        
        public  string UserName
        {
            get { return m_UserName; }
            set    
            {
                if ( value != null)
                    if( value.Length > 64)
                        throw new ArgumentOutOfRangeException("Invalid value for UserName", value, value.ToString());
                
                m_IsChanged |= (m_UserName != value); m_UserName = value;
            }
        }
            
        /**//// <summary>
        /// 
        /// </summary>        
        public  string Password
        {
            get { return m_Password; }
            set    
            {
                if ( value != null)
                    if( value.Length > 32)
                        throw new ArgumentOutOfRangeException("Invalid value for Password", value, value.ToString());
                
                m_IsChanged |= (m_Password != value); m_Password = value;
            }
        }
            
        /**//// <summary>
        /// 
        /// </summary>        
        public  string Email
        {
            get { return m_Email; }
            set    
            {
                if ( value != null)
                    if( value.Length > 64)
                        throw new ArgumentOutOfRangeException("Invalid value for Email", value, value.ToString());
                
                m_IsChanged |= (m_Email != value); m_Email = value;
            }
        }
            
        /**//// <summary>
        /// 对象的值是否被改变
        /// </summary>
        public bool IsChanged
        {
            get { return m_IsChanged; }
        }
        
        /**//// <summary>
        /// 对象是否已经被删除
        /// </summary>
        public bool IsDeleted
        {
            get { return m_IsDeleted; }
        }
        
        #endregion 
        
        公有函数#region 公有函数
        
        /**//// <summary>
        /// 标记对象已删除
        /// </summary>
        public void MarkAsDeleted()
        {
            m_IsDeleted = true;
            m_IsChanged = true;
        }
        
        
        #endregion
        
        重写Equals和HashCode#region 重写Equals和HashCode
        /**//// <summary>
        /// 用唯一值实现Equals
        /// </summary>
        public override bool Equals( object obj )
        {
            if( this == obj ) return true;
            if( ( obj == null ) || ( obj.GetType() != this.GetType() ) ) return false;
            User castObj = (User)obj; 
            return ( castObj != null ) &&
                ( this.m_UserId == castObj.UserId );
        }
        
        /**//// <summary>
        /// 用唯一值实现GetHashCode
        /// </summary>
        public override int GetHashCode()
        {
            
            int hash = 57; 
            hash = 27 * hash * m_UserId.GetHashCode();
            return hash; 
        }
        #endregion
        
    }
}
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
    <class name="MyNamePlace.User,MyAssembly" table="T_User">
 
        <id name="UserId" column="UserId" type="Int32" unsaved-value="0">
            <generator class="native"/>
        </id>
        <property column="UserName" type="String" name="UserName" not-null="true" length="64" />
        <property column="Password" type="String" name="Password" not-null="true" length="32" />
        <property column="Email" type="String" name="Email" length="64" />
        
    </class>
</hibernate-mapping>

备注:
        我的数据库表名以"T_"开头,生成类时我会用"_"后面的内容。例如:T_Parent对应的类是Parent。如果你的表名中没有"_"。将会取表名做类名。
如果你在设计数据表时把字段的描述加上,生成的代码文件的注释中将会有属性的描述。

注意:在把他们加入Visual Studio后别忘了设置为嵌入的资源。

生成关系

在Template Browser里面的NHibernate找到"DDL NHibernate Relation Mapping"。运行此模版

选择你需要的表,需要的关系。点OK。

我们以双向的one-to-many为例

你可以看到下面的生成代码。

//Parent
<bag name="Childs" cascade="all" lazy="true" inverse="true">
    <key column="ParentId"></key>
    <one-to-many class="MyNamePlace.Child,MyAssembly"></one-to-many>
    </bag>
 
    private IList m_Child=new ArrayList();
 
public IList Childs
{
    get{return m_Child;}
    set{m_Child=value;}
}
 
//Child
<many-to-one name="Parent" column="ParentId"
    class="MyNamePlace.Parent,MyAssembly" />
 
    private Parent m_Parent;
 
public Parent Parent
{
    get{return m_Parent;}
    set{m_Parent=value;}
}

把他们拷贝到你生成的模版文件里面。“//Parent”后面的拷贝到Parent的映射类文件和.hbm.xml文件中。“//Child”后面的拷贝到Child的映射类文件和.hbm.xml文件中。

注意:需要把Child类和.hbm.xml里的ParentId去掉,不然会出现两个属性映射到一个字段的错误。

DDL NHibernate Relation Mapping模板使用注意:

    保持主外键的名称一致,比如T_Parent中主键名为ParetId,T_Child中与其参照的外键名也为ParentId。

    主表先选择,Parent-Child关系中先选择Parent,Person-Employee关系中先选择Person。

    多对多关系才会用到中间表下拉框。

其他的关系生成操作方法类似,我不再复述。

如果你对关联不是很熟悉请参见NHibernate的关联映射(one-to-one,one-to-many,many-to-many)以及cascade分析。本模版生成的文件都使用NHibernate的关联映射(one-to-one,one-to-many,many-to-many)以及cascade分析一文的典型设置。可以满足绝大部分的情况。当然你也可以适当修改后使用。
模版更新:

    增加了对Guid主键的支持,中文的注释,其他代码改善,部分代码提取到自定义的基类。

     2006.8.24 修改部分bug

DDLNHibernateDotNetScriptTemplate.dll   源码,可以自己重新编译。

using System;
using System.Globalization;
using System.Text.RegularExpressions;
using Dnp.Utils;
using MyMeta;
using Zeus;
using Zeus.DotNetScript;
using Zeus.UserInterface;
 
namespace DDLLY.MyGenerationTemplate
{
    public abstract class DDLNHibernateDotNetScriptTemplate : _DotNetScriptTemplate
    {
        protected GuiController ui;
        protected dbRoot MyMeta;
        protected Utils DnpUtils;
 
        public DDLNHibernateDotNetScriptTemplate(IZeusContext context)
            : base(context)
        {
            ui = context.Objects["ui"] as GuiController;
            MyMeta = context.Objects["MyMeta"] as dbRoot;
            DnpUtils = context.Objects["DnpUtils"] as Utils;
        }
 
        /**//// <summary>
        /// 前缀
        /// </summary>
        protected string _prefix;
        
        /**//// <summary>
        /// 创建XML
        /// </summary>
        protected bool _CreatingXML = false;
 
        protected string _NullSufix;
 
        
        protected string ConvertNHibernate(string Type)
        {
            string retVal = Type;
 
            switch (Type)
            {
                case "bool":
                    retVal = "Boolean";
                    break;
                case "byte":
                    retVal = "Byte";
                    break;
                case "sbyte":
                    retVal = "SByte";
                    break;
                case "char":
                    retVal = "Char";
                    break;
                case "decimal":
                    retVal = "Decimal";
                    break;
                case "double":
                    retVal = "Double";
                    break;
                case "float":
                    retVal = "Single";
                    break;
                case "int":
                    retVal = "Int32";
                    break;
                case "uint":
                    retVal = "UInt32";
                    break;
                case "long":
                    retVal = "Int64";
                    break;
                case "ulong":
                    retVal = "UInt64";
                    break;
                case "short":
                    retVal = "Int16";
                    break;
                case "ushort":
                    retVal = "UInt16";
                    break;
                case "string":
                    retVal = "String";
                    break;
            }
 
            return retVal;
        }
 
        //protected string ColumnToMemberVariable(IColumn Column)
        //{
        //    return _prefix + UniqueColumn(Column).ToLower();
        //}
 
        //protected string ColumnToPropertyName(IColumn Column)
        //{
        //    return ToPascalCase(UniqueColumn(Column));
        //}
 
        //protected string ColumnToArgumentName(IColumn Column)
        //{
        //    return UniqueColumn(Column).ToLower();
        //}
 
        //protected string ColumnToNHibernateProperty(IColumn Column)
        //{
        //    return _prefix + UniqueColumn(Column);
        //}
 
 
        // nhibernate doesn't have these, so use the existing types
        protected string ColumnToNHibernateType(IColumn Column)
        {
            string retVal = Column.LanguageType;
 
            switch (retVal)
            {
                case "sbyte":
                    retVal = "byte";
                    break;
                case "uint":
                    retVal = "int";
                    break;
                case "ulong":
                    retVal = "long";
                    break;
                case "ushort":
                    retVal = "short";
                    break;
                case "bool":
                case "decimal":
                case "float":
                case "byte":
                case "short":
                case "int":
                case "long":
                    if (!_CreatingXML)
                    {
                        if (Column.IsNullable)
                        {
                            retVal = retVal + _NullSufix;
                        }
                    }
                    break;
            }
 
            return retVal;
        }
 
        /**// <summary>
        / 首字母大写
        / </summary>
        / <param name="name"></param>
        / <returns></returns>
        //protected string ToLeadingCaps(string name)
        //{
        //    char[] chars = name.ToLower().ToCharArray();
        //    chars[0] = Char.ToUpper(chars[0]);
        //    return new string(chars);
        //}
 
        /**//// <summary>
        /// 首字母小写
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        private string ToLeadingLower(string name)
        {
            char[] chars = name.ToCharArray();
            chars[0] = Char.ToLower(chars[0]);
            return new string(chars);
        }
        
        /**//// <summary>
        /// 私有成员名
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        protected string ToVariableName(string name)
        {
            return _prefix + name;
        }
        
        /**//// <summary>
        /// 参数名
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        protected string ToArgumentName(string name)
        {
            return ToLeadingLower(name);
        }
 
        /**// <summary>
        / 统计必需(不允许空)的的字段个数
        / </summary>
        / <param name="Columns"></param>
        / <returns></returns>
        //protected int CountRequiredFields(IColumns Columns)
        //{
        //    return Columns.Count - CountNullableFields(Columns);
        //}
 
        /**// <summary>
        / 统计允许为空的字段个数
        / </summary>
        / <param name="Columns"></param>
        / <returns></returns>
        //protected int CountNullableFields(IColumns Columns)
        //{
        //    int i = 0;
        //    foreach (IColumn c in Columns)
        //    {
        //        if (c.IsNullable)
        //        {
        //            i++;
        //        }
        //    }
        //    return i;
        //}
 
        /**//// <summary>
        /// 统计唯一字段的个数(非空且为主键)
        /// </summary>
        /// <param name="Columns"></param>
        /// <returns></returns>
        protected int CountUniqueFields(IColumns Columns)
        {
            int i = 0;
            foreach (IColumn c in Columns)
            {
                if (!c.IsNullable && c.IsInPrimaryKey)
                {
                    i++;
                }
            }
            return i;
        }
        
        /**//// <summary>
        /// 根据IColumn获得不同的Generator
        /// </summary>
        /// <param name="Column"></param>
        /// <returns></returns>
        protected string GetGeneratorString(IColumn Column)
        {
 
            if (Column.DataTypeName == "uniqueidentifier")
            {
                return "guid";
            }
            
            if(Column.IsAutoKey)
            {
                return "native";
            }
            else
            {
                return "assigned";
            }
        }
        
        /**//// <summary>
        /// 表名转换为类名
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        protected string TableNameToClassName(string tableName)
        {
            int index = tableName.LastIndexOf("_");
            return tableName.Substring(index + 1);
        }
    }
}

需要引用以下类库(都在MyGeneration的安装路径里):
Dnp.Utils.dll
DotNetScriptingEngine.dll
MyMeta.dll
PluginInterfaces.dll
Zeus.dll

转载于:https://www.cnblogs.com/sczw-maqing/p/3373789.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值