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

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

  1. 用MyGeneration模板生成NHibernate映射文件和关系

    用我的MyGeneration模板生成NHibernate映射文件和关系(one-to-one,one-to-many,many-to-many) MyGeneration的几个NHibernate模 ...

  2. 咱就入个门之NHibernate映射文件配置(二)

    上一篇主要介绍了NHibernate映射文件的基础配置,这篇我们介绍下NHibernate的一对多及多对一配置(文中我直接使用双向关联,即一和多两端都配置,开发中可以只使用一端),同时略带介绍下NHi ...

  3. 用MyEclipse自动生成hibernate映射文件和实体类

    创建数据库,创建相应的表 点击图标,选择MyEclipse Datebase Explorer 右击空白区域,选择new菜单,根据提示创建数据库连接,创建好后会显示你所创建的连接名,如图mysqldb ...

  4. 命令+mybatis-generator插件自己主动生成Mapper映射文件

    学mybatis的时候,自己写各种 *Mapper.xml和 *Mapper.java,注意各种sql语句中的 id 是否匹配.xml中的namespace是否正确,非常麻烦有木有?今天博客内容就是高 ...

  5. 生成 hibernate 映射文件和实体类

    创建web工程,使用Hibernate的时候,在工程里一个一个创建实体类太麻烦,浪费时间,现在教大家如何用MyEclipse自动生成Hibernate映射文件及实体类 方法/步骤   创建数据库,创建 ...

  6. 咱就入个门之NHibernate映射文件配置(一)

    之前写了数据库连接配置,这次说说映射文件的配置,即表映射[ORM的核心就是此啦!]. 下面我们使用最原始的手动配置hbm.xml文件. 步骤: 1.添加People类 namespace NHiber ...

  7. SQL映射文件-----MySQL关系映射【1对1,1对多,多对多】

    SSM框架下,mapper.xml 中 association 标签和 collection 标签的使用 当数据库中表与表之间有关联时,在对数据库进行操作时,就不只是针对某一张表了,需要联表查询 My ...

  8. XML映射文件中关系映射

    映射(多)对一.(一)对一的关联关系 1).使用列的别名 ①.若不关联数据表,则可以得到关联对象的id属性 ②.若还希望得到关联对象的其它属性.则必须关联其它的数据表 1.创建表: 员工表: DROP ...

  9. 在MVC架构中使用CodeSmith生成NHibernate映射对象和实体类

    第一步:找到生成模板,如下图 第二步:配置数据库连接(如下图),然后右击第一步找到的模板,点击Excute 第三步:执行操做(如下图) 第四步: 找到之前配置生成的文件夹,找到如下文件(图中标记的文件 ...

随机推荐

  1. LA 3516 (计数 DP) Exploring Pyramids

    设d(i, j)为连续子序列[i, j]构成数的个数,因为遍历从根节点出发最终要回溯到根节点,所以边界情况是:d(i, i) = 1; 如果s[i] != s[j], d(i, j) = 0 假设第一 ...

  2. CodeForces Round #290 Fox And Dinner

    而是Div2的最后一题,当时打比赛的时候还不会最大流.自己能够把它写出来然后1A还是很开心的. 题意: 有n个不小于2的整数,现在要把他们分成若干个圈.在每个圈中,数字的个数不少于3个,而且相邻的两个 ...

  3. UVa 1636 (概率) Headshot

    既然是第一道概率题,就正儿八经地分析一下吧. 题意: 有一个左轮枪,里面随机装了或者没装子弹,用一个01序列表示.现在已知扣动第一次扳机没有子弹,问是继续扣动扳机还是随机转动一下再扣,那种选择使得第二 ...

  4. 英文 数字 不换行 撑破div容器

    我们在div等容器 中,如果规定了宽度,并且里面的内容不是全英文或者全数字是OK的,会自动换行,但是如果是全数字或者是全英文,则会撑破容器,如图     解决方法 word-wrap:break-wo ...

  5. BZOJ 1610 连线游戏

    BZOJ不允许除以0. #include<iostream> #include<cstdio> #include<cstring> #include<cstd ...

  6. ffmpeg基础与编译_在VS2008下调试output_example.c(详细步骤)

    注意:这个是编译Debug版本的.必要资源:FFMPEG SDK 3.2(已经编译好的,可以去http://www.bairuitech.com/html/ruanjianxiazai/ffmpeg/ ...

  7. Android精美的日历控件

    网上看到的精美日历控件,谨以此文记录一下,用到的时候再来翻翻 源码地址 : http://download.csdn.net/detail/abc13939746593/7265459

  8. Android手动画柱状图的例子

    效果图如上,网上看到的例子,谨以此文记录一下,以后用到的地方再来翻翻. 核心技术是用Canvas和Paint画长方形. 源码地址:http://download.csdn.net/detail/abc ...

  9. 【转】Android fill_parent和wrap_content分析

    fill_parent设置一个顶部布局或控件强制性让它布满整个屏幕. wrap_content布局指根据视图内部内容自动扩展以适应其大小. 1. wrap_content <?xml versi ...

  10. group by调优的一些测试

    表结构信息: mysql> show create table tb\G*************************** 1. row ************************** ...