Kanas.net Framework 入门介绍
一、关于模型及领域代码
数据模型来自唯一的ERM文档,通过提供的Kanas.ModelBroker.Exe工具可以编辑和生成Erm文档,不过我还是建议你从以下两个途径获取文档:
1.通过Microsoft Visual Studio.net 2003所带的Visio做数据库建模(数据库模型图),将结果导出为ERX文档(可使用任何一个版本),再通过Kanas.ModelBroker导入,保存为Erm文档。
2.通过SyBase PowerDesigner10.0/11.0建模型,保存为Pdm(Xml格式)文档,然后通过Kanas.ModelBroker导入,保存为Erm文档。
需要说明的是:Kanas.ModelBroker.Dom以及Kanas.ModelBroker.Extension包括一组非常简单的开放式接口,支持导入任何格式的模型文档。虽然Kanas.ModelBroker也支持从数据库Schema导入,但我绝不推荐,因为大多数数据库Schema不包括逻辑关系。
从模型文档导入的Erm文档能够识别一些简单的关系,但是还需要作一些简单的修改才能生成理想的领域模型代码。主要有以下几点:
1.领域说明:对每个实体、每个属性都应该进行领域注释,生成代码后将在代码中包括这些注释,也可以生成相关的Xml文档甚至MSDN风格的文档,在VS.Net还支持自动注释。
2.逻辑关系:导入时大部分引用关系已经析出,但如果有一些关系未被析出的话,可以手工设置。将类型设置为Entity:XXXX(实体引用)或Enum:XXXX(枚举引用)将获得逻辑关系。这些关系不依赖数据库Schema支持。如果被引用的类型为复合关键字(绝不推荐),则需要删除其余的属性并设置好Joining。
3.继承关系:修改实体的Super属性,则可令实体从另外一个实体派生。派生实体的Joining属性将与基类实体的关键属性连接。如果基类实体为复合关键字(绝不推荐),则派生实体的Joining为多个名称(将与数据库字对应)通过逗号分隔。
4.聚合关系:聚合关系是领域相关的,所以不能自动析出,必须手工设置。设置聚合时,只需在引用属性中将Aggregated属性设为领域属性名即可。例如:订单和订单明细项,在订单明细项对订单的引用属性中将Aggregated属性设为Items,则在生成的代码中订单将有一个Item属性,在对该属性首次访问时惰性加载。
通过Erm文档,Kanas.ModelBroker可以自动生成XXX.cs或XXX.vb文档作为领域代码,同时也能够生成Entity.cs或Entity.vb作为领域词典代码。虽然领域词典代码不是必须的,但我还是强烈推荐你使用这个代码。通过领域字典型代码可以获得以下功能:
1.类型化的CreateInstance方法,可以为只读字段设置构造参数。
2.生成强类型查询语句,例如:context.Select(Entity.OrderItem.Order == (Entity.Product.Category == (Entity.ProductCategory.Name == "Fruit"))),甚至包括一些非常复杂的查询。与SQL/HQL这样的脚本语言相比,这些语句是带设计期类型检查的,可避免设计时的低级错误。
Erm文档也可能通过另外一个工具实现与XXX.cs和Entity.cs代码的自动同步。这样在做一些小的改动时不必通过Kanas.ModelBroker来生成。具体过程是:
1.将所有的工具复制到一个固定的文件夹中(例如C:\Program Files\Kanas.Net\Bin),并将该文件夹路径设置到LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.1\AssemblyFolders下,令VS.Net2003可以找到这些文档;
2.导入Kanas.ModelBroker.reg到注册器,将Kanas.ModelBroker.VsTool.Dll作为一个COM插件安装到VS.Net中。
3.为项目中的Erm文档的属性设置自定义工具属性:KanasCodeGen。
4.当通过Xml编辑器修改过Erm文件后,相关的代码文档将会自动同步。当然,也可以通过上下文菜单中的“运行自定义工具”来手工同步。
二、关于简单的使用
Kanas.net Framework能够完全地隐藏数据库背景。通过领域代码即可以使用所有的业务操作。不过有两个最基本的概念需要说明:
1.业务上下文(AppContext):业务上下文是一个最基本的对象,不能直接创建,只能通过一个“唯一对象”通过AppContext.GetContext()方法获取。同一个“唯一对象”将获取同一个AppContext实例。在单元测试中,可以通过Guid.NewGuid()方法获取一个“唯一对象”,在Asp.net中可以通过Session.SessionID来获取一个“唯一对象”。AppContext只能通过AppContext.ReleaseContext手工销毁或者随AppDomain的释放或Session的释放自动销毁。
业务上下文将负责业务对象的加载、整个对象缓存(ObjectSpace)及数据库事务。
2.约束子(Constraint):约束子用于描述一组对象,例如符合某个条件的一组对象。约束子可以进行逻辑运算。Kanas.Net的查询都是通过约束子来实现的。不同的数据适配器也通过约束子来实现对象的筛选。当不通过领域词典代码工作时,就必须通过手工构造约束子来实现查询。
这样通过业务上下文及约束子就可以进行以下业务操作了:
1.新建业务对象并保存:
添加一个产品:
Product p = Entity.Product.CreateInstance();
p.Name = "青苹果";
p.Category = context.Select(Entity.Category.Name == "水果类")[0] as Category;
p.Producing = "美国";
p.Comment = "美国青苹果";
context.Attach(p); // 加入到上下文
context.ApplyTransactions(); // 提交事务
2.修改业务对象并保存:
将产地为“苏联”的产品的产地改为“俄罗斯”:
foreach (Product p in context.Select(Entity.Product.Producing == "苏联"))
{
p.Producing = "俄罗斯";
}
context.ApplyTransactions();
3.删除业务对象并保存:
删除所有类别已过期的产品:
foreach (Product p in context.Select(Entity.Product.Category == (Entity.ProductCategory.Expiration == true)))
{
context.Detach(p);
}
context.ApplyTransactions();
4.简单查询:
获取包括今天发运的订单:
IList list = context.Select(Entity.Order.OrderItem == (Entity.OrderItem.ShipDate == DateTime.Now));
最后,通过Kanas.Common提供的ObjectScope可以很快地将查询结果转换到一个DataTable中,并可以提供多种方式的编辑和保存。