zoukankan      html  css  js  c++  java
  • NewLife.Xcode 上手指南(三) 扩展属性的使用

    一、什么是扩展属性

    很多ORM框架都支持类似这样的操作.以第一节的表为例,

    image_thumb22

    象这样的Subject对象中有TeacherID的一般都是这样用

                Subject subject = Subject.FindByID(1);
                string TeacherName = subject.Teacher.Name;

    image

    这样子的话,直接就关联到Teacher对象,而不是在操作TeacherID,这是怎么做的呢? XCode会帮我们自动完成吗?

    首先我们肯定XCode是会帮我们自动来做这些扩展属性的.不信,大家可以看一下Teacher对象的Teacher.Biz.cs,里面已经有了这样的一段代码
    image

    XCode是如何帮我们绑定这些属性的呢?

    1.根据约定胜于配置,与其我们配置来配置去,让很多人无从上手,不如约定规则,这样更方便大家使用.于是XCode代码生成器中的帮助里有这么几条规则

    image

    nvarchar 和 varchar 的区别是存储方式不同  
    varchar是按字节存储的.而带"n"的nvarchar是按字符存储的  
    比如说 varchar(40),能存储40个字节长度的字符,存储中文字符的时候,因为中文字符1个字符就等于2个字节.所以varchar(40)只能存储20个中文字符. 
     nvarchar(40),就可以存储40个中文字符,也就是说可以存储80个字节长度的字符.nvarchar要相对于存储的字符类型.比如有些字符是占3个字节的.  
    需要trim的是(n)char....

    3.第6条XCode会自动把数据库注释生成为代码注释,如果没有注释XCode也会尝试自动翻译(这里是连接Google翻译器? 我想XCode不会真的自己集成了个字典吧~~~)

    4.想要自动生成扩展属性,从表的字段命名规则为(主表名+主表主键字段) ,这里有Subject表中存在TeacherID,又有Teacher表中以ID为主键 所以就能关联生成扩展属性.

    5.似乎一些扩展查询是根据索引来的,如果你建立了以TeacherID和Subject.Name为主的索引,似乎XCode会在Subject表中生成一个这样的查询方法,FindAllByTeacherIDAndSubjectName(int teacherid,string subjectname);

    6.最主要是请放弃那些无意义的前最tbl拉,tb拉,tab拉,tab_Student这些表名都不要用,直接用Student简洁明了

    二、XCode中如何自己写扩展属性

    就像上面的例子中,Teacher对象中已经有了扩展属性EntityList<Subject> Subjects;  但是Subject中似乎没有给我们自动生成扩展属性Teacher,这里我们就自己来写一个把,其实很简单

            #region 扩展属性
    
            private Teacher _Teacher;
    
            public Teacher Teacher
            {
                get
                {
                    if (_Teacher == null && _TeacherID > 0 && !Dirtys.ContainsKey("Teacher"))
                    {
                        _Teacher = Domain.Teacher.FindByID(_TeacherID);
                        Dirtys["Teacher"] = true;
                    }
                    return _Teacher;
                }
                set { _Teacher = value; }
    
            }
    
            #endregion

    image

    这里解释下代码,为什么这么写扩展属性,根据楼主的理解,Dirtys是一个字典,标识这个Teacher有没有查过,为什么要用这个标志来标识呢,

    应该是基于这样一种考虑,如果Teacher!=null那么肯定Teacher已经是查过了的,但是万一Teacher查过数据库了仍然是null,那么就需要一个标识来记录,我已经查过数据库拉,就算Teacher==null也不用再查拉,直接返回null吧,这样来减少数据库的查询,提高Cache命中率.

    这样写好之后,就可以在前台利用subject.Teacher来获得教师的属性拉.

    我们来测试下.

    先给Teacher表加点数据,在这里发现个第一节的bug,Phone竟然用的是Int类型,025输入变成25,输入手机号超出int的范围,这是个bug如何修复呢,首先我们修改数据库,其次利用Xcode代码生成器针对这个表重新生成一下.然后覆盖项目中的2个文件,这里Teacher.My.cs就体现出优势了,我们自己的代码完全不怕误操作覆盖.

    image

    这里,我们替换修改下数据库,

    image

    生成下代码,同样是实体数据和实体业务都生成一遍,然后得到2个文件,覆盖之

    image

    image

    继续我们的添加数据的操作,在subject里加点料.

    image

    在这里,我们加了3条数据,主要是测试XCode是不是如我们的猜想一样,命中Cache不用查数据库.

    为了查看到SQL语句,请确保config里这2个开关已经打开,第二讲中我复制了这些语句,但是忘记打开开关了…jiong一个

    image

      <appSettings>
        <!--是?否?启?用?调獭?试?,?默?认?不?启?用?-->
        <add key="XCode.Debug" value="true"/>
        <!--是?否?输?出?SQL语?句?,?默?认?为aXCode调獭?试?开a关?XCode.Debug-->
        <add key="XCode.ShowSQL" value="true"/>
        <!--设Θ?置?SQL输?出?的?单蹋?独à目?录?,?默?认?为a空?,?SQL输?出?到?当獭?前°日?志?中D。£生Θ?产ú环·境3建¨议皑?输?出?到?站?点?外猘单蹋?独à的?SqlLog目?录?-->
        <add key="XCode.SQLPath" value=""/>
        <!--是?否?启?用?反ぁ?向ò工¤程ì,?默?认?不?启?用?。£反ぁ?向ò工¤程ì可é以?实害?现?通?过y实害?体?类え?反ぁ?向ò更ü新?数簓据Y库a结á构1-->
        <add key="XCode.Negative.Enable" value="true"/>
      </appSettings>
    我不得不说,我的代码着色器对中文支持很烂哎````

    三、开始测试

            直接建立一个新的页面,叫test.aspx来做今天的测试吧~~~我已经从7点半写到8点40了...还没结束呢...我已经不想写完整的例子了...拿个页面做个简单测试吧..

    image

            protected void Page_Load(object sender, EventArgs e)
            {
                Domain.Subject subject1 = Domain.Subject.FindByID(1);
                Response.Write(string.Format("第{0}个科目,科目名称:{1},任课老师:{2},任课老师办公室:{3},任课老师电话:{4}<br/>",
                                             subject1.ID, subject1.Name, subject1.Teacher.Name, subject1.Teacher.Office,
                                             subject1.Teacher.Phone));
    
                
                Domain.Subject subject2 = Domain.Subject.FindByID(3);
                if(subject2.Teacher == null)
                {
                    Response.Write(string.Format("第{0}个科目,科目名称:{1},任课教师为null",subject2.ID,subject2.Name));
                }
    
            }

    如果没有配置SQLPath的话,可以直接在项目根目录下,有个log文件夹,然后以日期命名的txt就是SQL日志.可以进去查看到系统运行时下的SQL

    image

    最后我发现...我的猜想都错了....XCode初始化了所有的实体,然后全部从Cache命中.....初始化完了之后一次SQL都没下....

    然后又发现,隔一段时间就会有2句Select * from teacher和subject ,估计应该是XCode的Cache更新时间到了,所以自动更新下最新的缓存.

    XCode内部的实现我就不纠结了,基本猜测方向没错,具体怎么实现的,各位看官自行阅读XCode的源码吧.XCode是开源的哦...

    本节就到这里,下一节我们介绍XCode的级联删除和更新. 下期再见~

    本节Demo

    http://dl.dbank.com/c0wyn9igvt

    XCode上手指南系列:

    NewLife.XCode 上手指南

    NewLife.XCode 上手指南(二) 反向工程使用举例

    NewLife论坛地址:

    http://www.newlifex.com/

    大石头博客:

    http://www.cnblogs.com/nnhy/

    NewLife.XCode开发资源目录

    http://www.cnblogs.com/asxinyu/archive/2012/06/02/2532210.html

  • 相关阅读:
    www.insidesql.org
    kevinekline----------------- SQLSERVER MVP
    Sys.dm_os_wait_stats Sys.dm_performance_counters
    如何使用 DBCC MEMORYSTATUS 命令来监视 SQL Server 2005 中的内存使用情况
    VITAM POST MORTEM – ANALYZING DEADLOCKED SCHEDULERS MINI DUMP FROM SQL SERVER
    Cargo, Rust’s Package Manager
    建筑识图入门(初学者 入门)
    Tracing SQL Queries in Real Time for MySQL Databases using WinDbg and Basic Assembler Knowledge
    Microsoft SQL Server R Services
    The Rambling DBA: Jonathan Kehayias
  • 原文地址:https://www.cnblogs.com/JangoJing/p/2616238.html
Copyright © 2011-2022 走看看