当前位置: 首页 > 编程日记 > 正文

5,ORM组件XCode(动手)

本篇才真正是XCode教程第一篇。《速览》是为了以最简洁的语言最短小的篇幅去吸引开发者;《简介》则是对XCode组件和XCode开发模式的一个整体介绍,让开发者从宏观的角度去理解XCode;《共舞》把XCode提到了一个新的高度,让开发者感受到它的贵族血统!

先抛出三篇来吸引人,再出《动手》,其实就是吊人胃口。如果到这里你还没有想试一试XCode的念头冲动,好吧,我承认是我的失败,不过你可以欺骗我,可别欺骗你自己!

XCode开发模式建议先有数据库再有实体模型,然后借助代码生成器生成实体代码;当然你要反过来先做实体模型也是可以的,XCode之下的实体,支持反向生成数据库结构。

下面以《速览》中的UserMember为例,建立数据表:

数据表名: 用户 (UserMember)

中文名

英文名

数据类型

大小

是否主键

是否唯一

是否必填

默认值

编号

ID

Int32

10

账号

Account

String

50

 

 

 

显示名

DisplayName

String

50

 

 

 

wps_clip_image-26120

数据库命名规范:

² 名称必须使用通俗易懂的英文单词全拼,常用的缩略词(如ID)除外

² 使用驼峰命名规则,每个单词首字母大写,其它小写

² 名称必须简洁明了,不要加多余的前缀(如表名前加tbl),字段名也不要加表名前缀

² 不得使用SQL关键字或C#关键字作为表名或字段名

² 布尔型字段名称必须是IsAbb的形式

² 字符串类型统一使用nvarchar,大文本使用ntext,除非特殊情况,否则不用其它文本类型

² 建议给每张表建立一个自增的ID字段并作为主键,以利于数据分页管理

² 建议给每张表和每个字段加上说明

使用代码生成器生成代码(先看代码,待会讲过程):

ExpandedBlockStart.gif代码
/// <summary>
/// 用户
/// </summary>
[Serializable]
[DataObject]
[Description(
"用户")]
[BindTable(
"UserMember", Description = "用户", ConnName = "Test")]
public partial class UserMember
{
    
#region 属性
    
private Int32 _ID;
    
/// <summary>
    
/// 编号
    
/// </summary>
    [Description("编号")]
    [DataObjectField(
truetruefalse10)]
    [BindColumn(
"ID", Description = "编号", DefaultValue = "", Order = 1)]
    
public Int32 ID
    {
        
get { return _ID; }
        
set { if (OnPropertyChange("ID", value)) _ID = value; }
    }
    
    
private String _Account;
    
/// <summary>
    
/// 账号
    
/// </summary>
    [Description("账号")]
    [DataObjectField(
falsefalsetrue50)]
    [BindColumn(
"Account", Description = "账号", DefaultValue = "", Order = 2)]
    
public String Account
    {
        
get { return _Account; }
        
set { if (OnPropertyChange("Account", value)) _Account = value; }
    }
    
    
private String _DisplayName;
    
/// <summary>
    
/// 显示名
    
/// </summary>
    [Description("显示名")]
    [DataObjectField(
falsefalsetrue50)]
    [BindColumn(
"DisplayName", Description = "显示名", DefaultValue = "", Order = 3)]
    
public String DisplayName
    {
        
get { return _DisplayName; }
        
set { if (OnPropertyChange("DisplayName", value)) _DisplayName = value; }
    }
    
#endregion

    
#region 获取/设置 字段值
    
/// <summary>
    
/// 获取/设置 字段值。
    
/// 一个索引,基类使用反射实现。
    
/// 派生实体类可重写该索引,以避免反射带来的性能损耗
    
/// </summary>
    
/// <param name="name">字段名</param>
    
/// <returns></returns>
    public override Object this[String name]
    {
        
get
        {
            
switch (name)
            {
                
case "ID"return ID;
                
case "Account"return Account;
                
case "DisplayName"return DisplayName;
                
defaultreturn base[name];
            }
        }
        
set
        {
            
switch (name)
            {
                
case "ID": _ID = Convert.ToInt32(value); break;
                
case "Account": _Account = Convert.ToString(value); break;
                
case "DisplayName": _DisplayName = Convert.ToString(value); break;
                
defaultbase[name] = value; break;
            }
        }
    }
    
#endregion

    
#region 字段名
    
/// <summary>
    
/// 取得字段名的快捷方式
    
/// </summary>
    public class _
    {
        
/// <summary>
        
/// 编号
        
/// </summary>
        public const String ID = "ID";
        
        
/// <summary>
        
/// 账号
        
/// </summary>
        public const String Account = "Account";
        
        
/// <summary>
        
/// 显示名
        
/// </summary>
        public const String DisplayName = "DisplayName";
    }
    
#endregion
}

代码不多,分为属性、索引器和嵌套类三大块,其中后两块还不是必须的,所以即使是手工编码也不会太麻烦。

所使用的代码生成器XCoder,是一个基于XCode的模版标签替换生成器。XCode提供数据库结构信息,用户设计模版,XCoder根据模版标签进行替换。上面的代码还有数据字典表格,都是XCoder生成的,只是所使用的模版不同而已。有兴趣的朋友完全可以定制自己的代码生成器,DAL类的Tables属性可以取得该连接的表架构信息,如DAL.Create("Test").Tables可以取得连接名为Test的数据库的架构信息。

XCoder的使用很简单,打开配置文件XCoder.exe.config,增加一个连接字符串:

ExpandedBlockStart.gif代码
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
<connectionStrings>
    
<add name="Test" connectionString="Data Source=.;Initial Catalog=Test;Integrated Security=True;" providerName="System.Data.SqlClient"/>
  
</connectionStrings>
</configuration>

运行XCoder.exe,可以在连接下拉框选择连接字符串

wps_clip_image-4220

点击连接,列出该库所有表和视图

wps_clip_image-15353

设置命名空间、输出目录和连接名等信息,选择“数据”模版,点击生成

wps_clip_image-19110

因为XCode是充血模型,使用的时候是不需要指定数据库连接的,所以实体类里面默认指定连接名。

XCode模型追求简单实用,所以没有区分数据层和业务层。但是XCode实体类有数据类和业务类的说法,刚才上面的“数据”模版生成的就是数据类,下面生成业务类

wps_clip_image-30238

可以看出,数据类和业务类其实就是同一类,只不过使用了分部类partial,把一个类分拆到两个文件里面去。数据类记录表结构信息,基本上依靠于生成;业务类第一次生成后只有一些注释,用于引导开发者如何实现自己想要的功能。业务代码等人工编写的代码,都要求卸载业务类里面,当表结构改变需要重新生成代码时,仅生成数据类即可,人工编写的代码保留在业务类中,不至于被覆盖。

XCoder在输出目录生成了代码文件,复制到vs里面去

wps_clip_image-3181wps_clip_image-25038

再看看例子代码

ExpandedBlockStart.gif代码
//新增数据,Save等效于Insert
UserMember user = new UserMember();
user.Account 
= "asdf";
user.Save();
//user.Insert();

//ID作为自增字段,保存后自动设为新值
Console.WriteLine(user.ID);

//查找数据,等效
user = UserMember.Find("Account""asdf");
user 
= UserMember.Find(UserMember._.Account, "asdf");

user 
= UserMember.FindByAccount("asdf");
user.DisplayName 
= "测试数据";

//读取成员数据,等效
String str = (String)user["DisplayName"];
str 
= user.DisplayName;

//给成员赋值,等效
user.DisplayName = "测试数据";
user[
"DisplayName"= "测试数据";

//保存数据,等效
user.Save();
//user.Update();

Console.WriteLine(user.ID);

user.Delete();

编译,提示user = UserMember.FindByAccount("asdf")这句报错,没有FindByAccout方法。忘了这是我手工写的了

public static UserMember FindByAccount(String account)
{
    
return Find(_.Account, account);
}

这个方法是根据账号查找用户。一般建议,FindByXxxx表示根据某个条件查询一个对象,FindAllByXxxx表示查询符合某个条件的所有对象的集合。

再次编译,通过。运行

wps_clip_image-12655

又忘了,我们还没有设置连接字符串呢。增加连接字符串

<add name="Test" connectionString="Data Source=.;Initial Catalog=Test;Integrated Security=True;" providerName="System.Data.SqlClient" />

这里要求连接名必须是Test,因为生成数据类的时候,指定了连接名为Test,所以才有刚才的异常,提示设置Test连接字符串。后面就是标准的连接字符串了,当然,这个时候是可以修改为Access、Oracle、MySql等连接字符串的,尽管我们开始的时候是在SqlServer中建立表结构。因为实体类已经建立完成,它与具体数据库无关,只有在运行时探测是哪一种数据库,再根据情况生成相应的查询/操作SQL。

XCode除了能获取数据库架构信息外,还能设置数据库架构,也就是能够根据实体类自动进行建表或者修改表结构。所以,不用担心修改连接字符串指向别的数据库后,会因为没有数据表而报错。这个小功能有个好处,比如生产环境是Oracle数据库,而开发环境比较差,跑不起Oracle,完全可以在开发环境用Access进行设计,部署到生成环境再修改连接字符串,XCode会尽其所能的屏蔽数据库操作差异。

打开XCode的OrmDebug开关(用于输出SQL语句),再次运行

wps_clip_image-18734

跟上面的代码进行比对,可以加深理解。OrmDebug开关对于学习XCode和解决问题非常有用。

上面是控制台的例子,下面看看Web的例子。

在生成实体类代码的时候,可以看到还有两个模版“列表页”和“表单”,取消“中文文件名”选择,分别生成这两个模版的代码。新建一个网站,把它们复制进去

wps_clip_image-19515wps_clip_image-2470

设置连接字符串,预览UserMember.aspx

wps_clip_image-19811

回到刚才的控制台代码,我们另外写一段插入测试数据的代码

for (int i = 0; i < 176; i++)
{
    UserMember user 
= new UserMember();
    user.Account 
= "User" + i;
    user.DisplayName 
= "用户" + i;
    user.Insert();
}

这段代码将会向数据库插入176行数据。刷新UserMember.aspx页面

wps_clip_image-24351

wps_clip_image-24647wps_clip_image-4652

wps_clip_image-4881

wps_clip_image-26768

列表显示、分页、排序、编辑、删除等功能都有了。

我们对这个页面做一点修改,添加一个到UserMemberForm.aspx的链接,并且把GridView里面的账号列改为超链接,也链接到UserMemberForm.aspx,并且带上ID作为参数。

wps_clip_image-19387

wps_clip_image-29363

点击“添加用户”

wps_clip_image-23060wps_clip_image-26119

添加一个用户

wps_clip_image-14110

点击账号aaa,进入表单编辑页面,注意地址栏的ID=179

wps_clip_image-29559

又一次,我们没有编写代码!

其实这些都是一些非常简单的功能,列表页就是GridView+ObjectDataSource +实体类,表单页就是FormView+ObjectDataSource+实体类,没有传递ID的时候为添加状态。

Web的例子就到这里,详细的用法可以回过头看看《与ObjectDataSource共舞》,里面提到的批量生产正是本篇所使用的代码生成器生成列表页和表单页。

大石头

新生命开发团队

2010-09-07 03:57

转载于:https://www.cnblogs.com/nnhy/archive/2010/09/15/1826602.html

相关文章:

前端知识分享.md

目录 一些支持固定列和表头的组件库element UIiViewAmaze UIlayui一些比较好的IDEMVVM 框架VueNode生态其它SassTypeScript一些支持固定列和表头的组件库 element UI https://element.eleme.cn/#/zh-CN/component/table iView https://www.iviewui.com/components/table Amaze …

C 输入 输出

C 输入 & 输出 当我们提到输入时&#xff0c;这意味着要向程序填充一些数据。输入可以是以文件的形式或从命令行中进行。C 语言提供了一系列内置的函数来读取给定的输入&#xff0c;并根据需要填充到程序中。 当我们提到输出时&#xff0c;这意味着要在屏幕上、打印机上或任…

搭建服务器环境 安装jdk、mysql、Tomcat 以及配置https 记录

1.在cenos上安装 jdk #在usr/local下创建 java 文件夹 mkdir java#将jdk拷贝到该文件夹中 [rootVM_0_15_centos jdk1.8.0_181]# cp jdk-8u181-linux-x64.tar.gz /usr/local/java/#解压该文件 [rootVM_0_15_centos jdk1.8.0_181]# tar -zxvf jdk-8u181-linux-x64.tar.gz #配置环…

一个Java程序员应该掌握的10项技能

1、语法&#xff1a;必须比较熟悉&#xff0c;在写代码的时候IDE的编辑器对某一行报错应该能够根据报错信息知道是什么样的语法错误并且知道任何修正。 2、命令&#xff1a;必须熟悉JDK带的一些常用命令及其常用选项&#xff0c;命令至少需要熟悉&#xff1a;appletviewer、 Ht…

逆向-攻防世界-maze

题目提示是走迷宫。 IDA载入程序分析。 输入字符长度必须是24&#xff0c;开头必须是nctf{&#xff0c;结尾必须是}。在125处按R就可以变成字符。 sub_400650和sub_400660是关键函数&#xff0c;分析sub_400650。 v10的下一字节减1. sub_400660v10的下一字节加1. 分析这两个函数…

linxu passwd 给linux用户设置密码 命令

[rootlocalhost ~]# passwd # 修改 root 用户的密码passwd 给linux用户设置密码 命令 passwd www 直接passwd是当前用户设置密码 非交互式修改密码&#xff1a; echo "123456" |passwd --stdin www [rootMongoDB ~]# echo "123456" | passwd…

MultipartFile 使用 记录

MultipartFile file 获取文件流 file.getInputStream()&#xff1b; 获取文件名称 String fileName file.getOriginalFilename(); 待补充

多语言加载图片问题

系统要求多语言&#xff1a;中文和英文&#xff0c;分别在两个xml文件中书写相关内容&#xff0c;类似&#xff1a; <root><resource name"VersionName">Version</resource><resource name"Logout">Logout</resource></r…

5.html基础标签:块级+行级元素+特殊字符+嵌套规则

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title> </head> <body><!-- 块元素&#xff1a;独立成一行(相当于标签前后都设置了br),可以设置宽高,默认宽高100%文字…

[摘]终于找到一个有助理解left/right/full outer join的例子

近日在学习《Understading DB2》的时候找到了一个例子&#xff0c;对于理解 left/right/full 三种 outer join 的大有裨益。 先看样本数据&#xff0c;来自DB2的示例数据库 sample&#xff1a; db2 > insert into employee values(99999,killkill,N,Huang,null,null,null,no…

vue——props的两种常用方法

vue——props的两种常用方法 1、实现父——>子的通信 举例如下&#xff1a; 父组件 parent.vue<children :channel"object1"></children> 子组件 children.vue export default{name:"children",props:["channel"],data(){return{…

idea导入模板

1.我的配置文件下载 请点下面的连接 https://download.csdn.net/download/huyande123/10728802 先导入第二个文件&#xff0c;在导入第一个文件 在此基础上添加了类注释和方法注释&#xff08;方法注释快捷键 qtab&#xff09; 参考链接 https://blog.csdn.net/qq_34581118…

为office添加繁简体转换

为office添加繁简体转换本人所在的公司是一间港资公司&#xff0c;很多香港同事习惯繁体&#xff0c;而我们内地的同事则习惯简体&#xff0c;于是免不了要进行繁简体转换&#xff0c;这时候就要装一个office的插件来达到这样的功能&#xff0c;如下&#xff1a;1、没装插件的时…

关闭Windows 7中的 Program Compatibility Assistant

感觉微软总喜欢把简单问题复杂化。安装几个小软件也老是弹出这样的对话框&#xff1a; 然后点击“What settings are applied?”&#xff0c;看到帮助中一段&#xff1a; 提示我在组策略里能够关闭这个烦人的程序兼容性助手&#xff0c;却没有明说&#xff0c;故意卖关子呢。那…

Swift学习:自动引用计数

swift 使用自动引用计数&#xff08;ARC&#xff09;机制来跟踪和管理你的应用程序的内存。通常情况下&#xff0c;swift 内存管理机制会一直起作用&#xff0c;你无须自己来考虑内存的管理。ARC 会在类的实例不再被使用时&#xff0c;自动释放其占用的内存。 然而在少数情况下…

简单又实用的分享!SharePoint母版页引用(实战)

分享人&#xff1a;广州华软 极简 一. 前言 此SharePoint 版本为2013&#xff0c;请注意版本号。此文以图文形式&#xff0c;描述了根网站及子网站引用母版页&#xff0c;需要注意的点已用图文形式以标明。 本文适用于初学者。 二. 目录 1. 前言 2. 目录 3. 如何引用母版页 4. …

mysql 修改某字段的格式为 utf8mb4

ALTER TABLE confession MODIFY content TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;#查看表中字段字符集 SHOW FULL COLUMNS FROM confession;

TileList自动滚动指定单元格,可视部分

TileList自动滚动指定单元格&#xff0c;可视部分 TileList1.scrollToIndex(50)

深入.NET DataTable

1、ADO.NET相关对象一句话介绍1)DataAdapter&#xff1a;DataAdapter实际是一个SQL语句集合&#xff0c;因为对Database的操作最终需要归结到SQL语句。2)Dataset&#xff1a;DataSet可以理解成若干DataTable的集合&#xff0c;DataSet在内存里面维护一个表集合包括表间关系。对…

天平称球问题-转

称球问题一般会有以下3种变形&#xff1a; 1、N个球&#xff0c;其中有一个坏的&#xff0c;知道是轻还是重&#xff0c;用天平称出坏球来。 2、N个球&#xff0c;其中有一个坏的&#xff0c;不知是轻还是重&#xff0c;用天平称出坏球来。 3、N个球&#xff0c;其中有一个坏…

Java虚拟机垃圾收集算法

1、标记-清除算法 标记-清除算法分为 “标记” 和 “清除” 两个步骤&#xff1a;首先标记出所有需要回收的对象&#xff0c;然后在标记完成后统一回收所有被标记的对象&#xff0c;是垃圾收集算法中的最基础的收集算法。 缺点&#xff1a;一、标记和清除两个步骤效率都不高&am…

WMIC的用法

获得系统版本信息wmic datafile where Namec:\\windows\\explorer.exe get Manufacturer,Version,Filename获得信筒进程 wmic process list full 注意&#xff1a;这里的full也可以换成brief&#xff08;简洁&#xff09;获得硬件信息&#xff08;这里以cpu为例&#xf…

洛谷P2763 试题库问题

题目&#xff1a;https://www.luogu.org/problemnew/show/P2763 题目描述 问题描述&#xff1a; 假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m 道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷…

梦断代码阅读笔记03

经过几天的阅读&#xff0c;终于将这本书看完了&#xff0c;读完了整个故事&#xff0c;我进行了简单的总结&#xff0c;感觉不仅仅是在写代码与计算机或软件交流&#xff0c;更多的是做事行为。 首先是做事得有目标。无论做什么事情都要有目标和动力&#xff0c;这样做起事来无…

能让导师喜欢的学生(转自论坛)

第一&#xff0c;明辨是非&#xff0c;从善如流。研究生是未来的高级知识分子&#xff0c;作为国家栋梁&#xff0c;将来很可能为国家和社会发展献计献策&#xff0c;如果不能明辨是非&#xff0c;如何做出正确建议和决策&#xff1f;如果不能从善如流&#xff0c;如何保证自己…

使用SpringBoot发送邮件 在本地测试是好的 放到服务器连接超时问题

原因 原来是ECS基于安全考虑&#xff0c;禁用了端口25。改成465就可以发邮件了。 原始配置 本地可发送 #spring.mail.hostsmtp.qq.com #spring.mail.usernameqq #spring.mail.passwordpassword #spring.mail.properties.mail.smtp.starttls.enabletrue #spring.mail.prope…

电脑中所有exe文件无法运行解决方案

电脑中所有exe文件无法运行。通过系统恢复无法解决毛病&#xff0c;后来才想起肯定是exe文件关联被改动&#xff0c;只有通过修改注册表才能改回来。要修改注册表就要运行regedit.exe文件&#xff0c;这也是一个exe文件&#xff0c;也无法运行。后来查资料找到了解决方法。现在…

[转]后期-快速消除痘痘,完美修复MM肌肤

是面对美景&#xff0c;即使皮肤不好也得露个脸啊!那MM的面子问题怎么办呢?简单&#xff0c;咱就通过Photoshop后期处理来<?xml:namespace prefix o />给MM打造完美水嫩的肌肤!远景照片 简单还原MM容颜日常拍摄的照片&#xff0c;很多时候是远景的拍摄&#xff0c;人物…

[Android] Android MVP 架构下 最简单的 代码实现

Android MVP 架构下 最简单的 代码实现 首先看图&#xff1a; 上图是MVP&#xff0c;下图是MVC MVP和MVC的区别&#xff0c;在于以前的View层不仅要和model层交互&#xff0c;还要和controller层交互。而在mvp中&#xff0c;view层只和presenter层交互&#xff0c;而model层也…

java项目上有个红色感叹号(在project Explorer视图下)

启动项目时一直报错&#xff0c;检查也没问题&#xff0c;最后看到项目上有个红色感叹号&#xff0c;发现是jar包路径不对&#xff0c;把错误路径的jar包移除&#xff0c;然后再重新添加即可。转载于:https://www.cnblogs.com/sanhao/p/8059257.html