XAF应用开发教程(二)业务对象模型之简单类型属性
使用过ORM的朋友对这一部分理解起来会非常快,如果没有请自行补习吧:D.
不说废话,首先,我们来开发一个简单的CRM系统,CRM系统第一个信息当然是客户信息。我们只做个简单 的客户信息来了解一下XAF好了。
新建项之后,可以看到如下代码界面:
using System;
using System.Linq;
using System.Text;
using DevExpress.Xpo;
using DevExpress.ExpressApp;
using System.ComponentModel;
using DevExpress.ExpressApp.DC;
using DevExpress.Data.Filtering;
using DevExpress.Persistent.Base;
using System.Collections.Generic;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation; namespace XCRMDemo.Module.BusinessObjects
{
[DefaultClassOptions]
//[ImageName("BO_Contact")]
//[DefaultProperty("DisplayMemberNameForLookupEditorsOfThisType")]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/eXpressAppFramework/CustomDocument112701.aspx).
public class 客户 : BaseObject
{ // Inherit from a different class to provide a custom primary key, concurrency and deletion behavior, etc. (https://documentation.devexpress.com/eXpressAppFramework/CustomDocument113146.aspx).
public 客户(Session session)
: base(session)
{
}
public override void AfterConstruction()
{
base.AfterConstruction();
// Place your initialization code here (https://documentation.devexpress.com/eXpressAppFramework/CustomDocument112834.aspx).
}
//private string _PersistentProperty;
//[XafDisplayName("My display name"), ToolTip("My hint message")]
//[ModelDefault("EditMask", "(000)-00"), Index(0), VisibleInListView(false)]
//[Persistent("DatabaseColumnName"), RuleRequiredField(DefaultContexts.Save)]
//public string PersistentProperty {
// get { return _PersistentProperty; }
// set { SetPropertyValue("PersistentProperty", ref _PersistentProperty, value); }
//} //[Action(Caption = "My UI Action", ConfirmationMessage = "Are you sure?", ImageName = "Attention", AutoCommit = true)]
//public void ActionMethod() {
// // Trigger a custom business logic for the current record in the UI (https://documentation.devexpress.com/eXpressAppFramework/CustomDocument112619.aspx).
// this.PersistentProperty = "Paid";
//}
}
}
1.为客户类填加属性,填加属性后将对应着数据库中的字段:
我将在代码中依次填加,姓名、禁用、性别、出生日期、手机号码、地址、年收入、照片,几个字段。
using System;
using System.Linq;
using System.Text;
using DevExpress.Xpo;
using DevExpress.ExpressApp;
using System.ComponentModel;
using DevExpress.ExpressApp.DC;
using DevExpress.Data.Filtering;
using DevExpress.Persistent.Base;
using System.Collections.Generic;
using System.Drawing;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation; namespace XCRMDemo.Module.BusinessObjects
{
[DefaultClassOptions]
//[ImageName("BO_Contact")]
//[DefaultProperty("DisplayMemberNameForLookupEditorsOfThisType")]
//[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
//[Persistent("DatabaseTableName")]
// Specify more UI options using a declarative approach (https://documentation.devexpress.com/eXpressAppFramework/CustomDocument112701.aspx).
public class 客户 : BaseObject
{
// Inherit from a different class to provide a custom primary key, concurrency and deletion behavior, etc. (https://documentation.devexpress.com/eXpressAppFramework/CustomDocument113146.aspx).
public 客户(Session session)
: base(session)
{
} public override void AfterConstruction()
{
base.AfterConstruction();
// Place your initialization code here (https://documentation.devexpress.com/eXpressAppFramework/CustomDocument112834.aspx).
} //姓名、禁用、性别、出生日期、手机号码、地址、年收入、照片
private string _姓名; public string 姓名
{
get { return _姓名; }
set { SetPropertyValue("姓名", ref _姓名, value); }
} private bool _禁用; public bool 禁用
{
get { return _禁用; }
set { SetPropertyValue("禁用", ref _禁用, value); }
} private 性别 _性别; public 性别 性别
{
get { return _性别; }
set { SetPropertyValue("性别", ref _性别, value); }
} private DateTime _出生日期; public DateTime 出生日期
{
get { return _出生日期; }
set { SetPropertyValue("出生日期", ref _出生日期, value); }
} private string _手机号码; public string 手机号码
{
get { return _手机号码; }
set { SetPropertyValue("手机号码", ref _手机号码, value); }
} private string _地址; public string 地址
{
get { return _地址; }
set { SetPropertyValue("地址", ref _地址, value); }
} private decimal _年收入; public decimal 年收入
{
get { return _年收入; }
set { SetPropertyValue("年收入", ref _年收入, value); }
} [Size(SizeAttribute.Unlimited), VisibleInListView(true)]
[ImageEditor(ListViewImageEditorMode = ImageEditorMode.PictureEdit,
DetailViewImageEditorMode = ImageEditorMode.PictureEdit,
ListViewImageEditorCustomHeight = )]
public byte[] 照片
{
get { return GetPropertyValue<byte[]>("照片"); }
set { SetPropertyValue<byte[]>("照片", value); }
}
} public enum 性别
{
男,女,未知
}
}
代码修改为上述内容后,我们再次运行系统,按下F5.
可以看到,我们新建的业务对象“客户”已经在菜中显示了,按下New按钮后,可以看到详细界面。
上面就是新建客户信息的界面了。下面我们来分析一下原理:
在代码中,我们使用了ORM工具,XPO定义了一个客户类,XPO运行时,分根据代码中的属性创建出数据库字段,下图是数据库中的表情况:
可以看出,xpo自动为我们建立了“客户”表,字段与“客户”类中的属性是一一对应的,但Oid,OptimisticLockField,GCRecord三个字段是我们没有建立的属性,却出现了,其中:
Oid,是GUID类型,主键,这是因为我们的代码中是这样写的:
public class 客户 : BaseObject Oid是在BaseObject中定义的,所以客户类会自动建立这个字段。 OptimisticLockField:是XAF为了解决并发冲突而建立的字段。 GCRecord:继承自BaseObject的类在删除记录时只是逻辑删除,即只是将GCRecord中记录一个值,而没有删除的记录则为Null.
属性的写法:
最简单的,当我们想在数据库中定义一个字段时,可以在xpo类中写一个属性,当然这种说法很肤浅,但是为了方便理解,刚开始时这样认为就可以了。
39 private string _姓名;
40
41 public string 姓名
42 {
43 get { return _姓名; }
44 set { SetPropertyValue("姓名", ref _姓名, value); }
45 }
这个属性和以往开发中的方法没有什么大的不同,仅是在set部分调用了SetPropertyValue方法,xpo为我们提供了一系列基类,SetPropertyValue是多数类中都有的,它的功能是可以在有值被设置时,需要得到属性变化时可以及时的得到通知。
当然,也可以直接使用
public string 姓名{get;set;}
这样来定义出姓名属性,但是有些场景时却会带来麻烦。
如:
public int 数量{get;set;}
public int 价格{get;set;}
public int 总价{get{return 数量*价格;}}
在数量和价格发生变化时,我们却看不到总价发生变化,因为控件不知道数量、价格已经变化了。所以我们应该尽量使用SetPropertyValue进行写set. 可以看到,字符串类型的姓名,在界面上最终显示成了一个文本框,XAF中内置了很多这样的控件,与类型做出了对应关系,当我们使用对应的类型时,就会自动使用对应的控件,这里的控件被叫做编辑器(PropertyEditor)。 接下来,有禁用属性:
private bool _禁用; public bool 禁用
{
get { return _禁用; }
set { SetPropertyValue("禁用", ref _禁用, value); }
}
同样的,在视图中可以看到一个CheckBox编辑器出现了。
private DateTime _出生日期; public DateTime 出生日期
{
get { return _出生日期; }
set { SetPropertyValue("出生日期", ref _出生日期, value); }
}
DateTime类型,直接使用CLR类型Datetime,日期型字段将在数据库中创建。
可以看出,xpo使用clr类型映射到了数据中字段的类型,下表中说明了数据库表中的字段类型与CLR类型的对应关系:
字段映射 除了自动建立的3个字段外,别的字段都是与代码有对应关系的映射了,xpo默认支持以下几种类型的映射:
C# System data type | Advantage | Asa | Ase | DB2 | Firebird | MySQL | MS Access | MSSQL | MSSQL CE | Oracle | Pervasive SQL | Postgre SQL | VistaDB |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
System.Boolean | logical | bit | bit | char(1) | char(1) | bit | bit | bit | bit | number(1,0) | bit | bool | Bit |
System.Byte | short | tinyint | tinyint | smallint | numeric(3,0) | tinyint unsigned | byte | tinyint | tinyint | number(3,0) | smallint | smallint | Int |
System.SByte | short | numeric(3,0) | numeric(3,0) | numeric(3,0) | numeric(3,0) | tinyint | short | numeric(3,0) | numeric(3,0) | number(3,0) | numeric(3,0) | smallint | SmallInt |
System.Char | char(1) | char(1) | nchar(1) | char(1) | char CHARACTER SET UNICODE_FSS | char | char(1) | nchar(1) | nchar(1) | nchar | char(1) | char(1) | NChar |
System.Decimal | money | money | money | decimal(28,4) | decimal(18,4) | double | currency | money | numeric(19,4) | number(19,5) | decimal(20,4) | decimal(28,8) | Decimal |
System.Double | double | double precision | double precision | double precision | double precision | double | double | double precision | float | double precision | double | double precision | Float |
System.Single | double | float | float | float | float | real | single | float | real | float | real | real | Float |
System.Int16 | short | smallint | smallint | smallint | smallint | smallint | short | smallint | smallint | number(5,0) | smallint | smallint | SmallInt |
System.UInt16 | integer | numeric(5,0) | numeric(5,0) | numeric(5,0) | numeric(5,0) | smallint unsigned | int | numeric(5,0) | numeric(5,0) | number(5,0) | numeric(5,0) | numeric(5,0) | Int |
System.Int32 | integer | int | numeric(10,0) | int | integer | int | int | int | int | int | integer | int | Int |
System.UInt32 | money | numeric(10,0) | numeric(10,0) | numeric(10,0) | numeric(10,0) | int unsigned | decimal(10,0) | numeric(10,0) | numeric(10,0) | numeric(10,0) | numeric(10,0) | numeric(10,0) | BigInt |
System.Int64 | money | bigint | numeric(20,0) | bigint | bigint | bigint | decimal(20,0) | bigint | bigint | number(20,0) | bigint | bigint | BigInt |
System.UInt64 | money | numeric(20,0) | numeric(20,0) | numeric(20,0) | numeric(18,0) | bigint unsigned | decimal(20,0) | numeric(20,0) | numeric(20,0) | number(20,0) | numeric(20,0) | numeric(20,0) | BigInt |
System.Guid | char(36) | UNIQUEIDENTIFIERSTR | char(36) | char(36) | char(36) | char(38) | guid | uniqueidentifier | uniqueidentifier | char(36) | char(36) | char(36) | UniqueIdentifier |
System.Enum | underlying type | underlying type | underlying type | underlying type | underlying type | underlying type | underlying type | underlying type | underlying type | underlying type | underlying type | underlying type | underlying type |
System.String | char | varchar | nvarchar | varchar | char varying | varchar | varchar | nvarchar | nvarchar | nvarchar2 | varchar | varchar | NVarChar |
System.DateTime | timestamp | datetime | datetime | timestamp | timestamp | datetime | datetime | datetime | datetime | date | timestamp | timestamp | DateTime |
System.TimeSpan | double | double precision | double precision | double precision | double precision | double | double | double precision | float | double precision | double | double precision | Float |
System.Byte[] | blob | image | image | blob | blob | LONGBLOB | longbinary | image, in SQL Server versions prior to 2005; otherwise - varbinary |
image | blob | longvarbinary | bytea | VarBinary |
Unlimited size string | memo | text | text | clob | BLOB SUB_TYPE TEXT | longtext | LONGTEXT | ntext, in SQL Server versions prior to 2005; otherwise - nvarchar |
ntext | nclob | longvarchar | text | NText |
上面所描述的是都简单类型,其中枚举类型、图像类型、颜色,相对特殊一些,例如枚举类型:
在代码中,我们可以看到如下属性定义
55 private 性别 _性别;
56
57 public 性别 性别
58 {
59 get { return _性别; }
60 set { SetPropertyValue("性别", ref _性别, value); }
61 }
这里的性别是一个枚举类型,定义如下:
107 public enum 性别
108 {
109 男,女,未知
110 }
打开详细视图,运行效果如下:
可以看出,XAF为我们使用类型进行了推导,自动使用了下拉框,并且取得到了枚举中有哪些值,显示在列表中供我们选择。XAF中的这种自动机制使用得非常多,后续我们将会看到。
图片的存储:
[Size(SizeAttribute.Unlimited), VisibleInListView(true)]
[ImageEditor(ListViewImageEditorMode = ImageEditorMode.PictureEdit,
DetailViewImageEditorMode = ImageEditorMode.PictureEdit,
ListViewImageEditorCustomHeight = )]
public byte[] 照片
{
get { return GetPropertyValue<byte[]>("照片"); }
set { SetPropertyValue<byte[]>("照片", value); }
}
图片的存储稍微有些不一样,在属性的get方法中,使用了GetPropertyValue<byte[]>来取值。
并且使用了几种Attribute,Attribute是为了扩展元数据的描述信息,简单来说,C#(.net)下面的语言不可能是无止境扩展的,所以提供了这样一种特殊的类,可以用来修饰程序中的无素,如assembly,class,interface,property,field,method等 等 .
xpo+xaf定义了很多的Attribute用来描述和扩展元数据信息,其中:
Size(SizeAttribute.Unlimited) 的意义是,创建数据库字段时,长度不限。SizeAttribute.Unlimited的值其实是-1,当然有些场景会用到限制长度。如
[Size(100)] //姓名字段数据库类型将是nvarchar(100)
public string 姓名{......}
[ImageEditor(ListViewImageEditorMode = ImageEditorMode.PictureEdit, DetailViewImageEditorMode = ImageEditorMode.PictureEdit,ListViewImageEditorCustomHeight = 40)]
这里设置了图像所使用的编辑器的参数,列表下面如何显示,详细视图下面如何显示,列表上显示时控制高度。 因为本节主要介绍业务对象的创建方法,不扩展讨论Attribute的用法,后续章节详细描述。 下节介绍几种常见的关系型数据库节构在ORM中的实现方法。
文章示例项目源码下载 QQ:4603528 QQ群:336090194
XAF应用开发教程(二)业务对象模型之简单类型属性的更多相关文章
- XAF应用开发教程(三)业务对象模型之引用类型与关联关系
本节介绍信息系统开发中最常见的问题,引用关系,一对多关系,多对多关系. 以客户信息为例,客户通常需要客户分类,如VIP客户,普通客户,潜在客户.当然,我们可以定义枚举类型进行定义出这个类型,并在客户类 ...
- MIP开发教程(二) 使用MIP-CLI工具调试MIP网页
初始化 MIP 配置 新建一个 MIP 网页 编写 MIP 网页代码 校验 MIP 网页 调试 MIP 网页 1. 初始化 MIP 配置 首先在html目录下进行初始化 MIP 配置: $ mip i ...
- 公众号第三方平台开发 教程二 component_verify_ticket和accessToken的获取
公众号第三方平台开发 教程一 创建公众号第三方平台 公众号第三方平台开发 教程二 component_verify_ticket和accessToken的获取 公众号第三方平台开发 教程三 微信公众号 ...
- XAF应用开发教程-内置Attribute功能列表
在 XAF 框架,一些用来生成一个业务应用程序的信息是在Attribute中指定.您可以将属性应用到业务类 (或它的成员) 指定验证规则,指定如何对数据进行显示. 设置关系类等.本主题提供了有关在何处 ...
- XAF应用开发教程(七)外观控制模块
很多时候,我们需要按照不同的条件显示不同的效果,在传统的软件开发中,我们会直接使用 控件名称.BackColor,Enable,Visible等属性进行控制. 如果一个业务对象在多处使用,要么我们会去 ...
- XAF应用开发教程(六)控制器
是的,XAF也是MVC结构的,但不仅限于MVC,ViewModel也存在,它是一项复合技术,AOP,ORM,MVC都有. 真实运行的系统中,仅有增删改查功能肯定是远远不够的,ERP.CRM等系统的开发 ...
- XAF应用开发教程(四)应用程序模型
XAF是重量型框架,确实够重量的,方方面面都做得规规矩矩. 如果看了前面三节,可能会认为,这N多的Attribute到底都是从哪里来的?到底有多少这样的Attribute?如果不够用了怎么办?等着官方 ...
- XAF应用开发教程(一) 创建项目
XAF是DevExpress公司的快速开发框架,全称eXpress Application Framework,是企业信息系统的开发利器,快速开发效果显著,在.net框架中,笔者至今没有找到一款可以与 ...
- XAF应用开发教程(八) 汉化与多国语言支持
使用了XAF开发时,汉化是一个比较常的问题. 要实现汉化很简单: 1.在这里下载汉化资源文件.这里演示的版本是15.1.X的 2.文件下载后将:文件解压到目录 <你的项目>\BIN\ ...
随机推荐
- nginx+tomcat负载均衡+动静分离+redis集中管理session
1.服务器A安装ng,服务器B.C安装tomcat: 2.服务器A建立/data/www目录,用于发布静态文件: 3.ng无动静分离配置: user root root; worker_process ...
- php的header()函数之设置content-type
//定义编码 header( 'Content-Type:text/html;charset=utf-8 '); //Atom header('Content-type: application/at ...
- easyui常现错误
1.easyui-tabs:当data-options的属性设置为true时,其tab内部的内容显示不出来. 2.设置easyui-panel的title格式及字体大小无效 解决方法:在设置title ...
- java中基础类型的初始值,以及一些平时不注意的小知识
有时候总是卡在一些类型的初始值上,今天闲下来就来自己给自己记录一下. String a; 如果直接打印会提示未初始化.并且未初始化的a不能比较. 这时,我们定义个person类 person{ S ...
- Number Sequence 分类: HDU 2015-06-19 20:54 10人阅读 评论(0) 收藏
Number Sequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ...
- Poj(2253),Dijkstra松弛条件的变形
题目链接:http://poj.org/problem?id=2253 题意: 给出两只青蛙的坐标A.B,和其他的n-2个坐标,任一两个坐标点间都是双向连通的.显然从A到B存在至少一条的通路,每一条通 ...
- 动态规划(DP),模拟
题目链接:http://poj.org/problem?id=1088 Memory: 252KTime: 16MSLanguage: C++Result: Accepted 解题报告: 1.lm[i ...
- servlet中Java连接数据库后的基本操作
servlet中Java连接数据库后的基本操作 在eclipse中新建一个工程:login 在Server中新建一个服务器,基本的操作不用说了,在前两天的笔记中可以找到; 需要知道数据库的用户名和密码 ...
- NOIP 营业额统计 splay tree 纯模板
2924: 营业额统计 Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal Submit: 389 ...
- zoj 3557 How Many Sets II
How Many Sets II Time Limit: 2 Seconds Memory Limit: 65536 KB Given a set S = {1, 2, ..., n}, n ...