Chapter Schema
Chapter Schema
Schema是XF的核心,每一个读写方法都有一个相关联的Schema。方法首先解析Schema,然后再根据Schema的配置的执行。
那Schema是什么呢?Schema是一个XElement,它的构成如下:
DatabaseSchema = Database Structure + NameMap + DatabaseConfig
PrimarySchema(一个) = DatabaseSchema + PrimaryConfig
NamedSchema(多个)= PrimarySchema + NamedConfig(多个)
Schema = PrimarySchema 或 NamedSchema + modifying(可选)
以上+号,代表Modify,+号右边的用来修改左边的,除了Database Structure与NameMap,其余均为XElement。
首先XF从数据库获得数据库结构(Database Structure),然后根据 NameMap,指定TableName、ColumnName与SetName 、ElementName、FieldName的映射。最后用DatabaseConfig修饰(Modify),得到DatabaseSchema。举例如下:
注:修饰(Modify)类似文件夹Copy,目标文件夹中存在的文件覆盖,不存在的添加。
如在数据库中有
Table:Users
PrimaryKey:Id
ColumnName |
DataType |
AllowDBNull |
Id |
int |
N |
UserName |
nvarchar(50) |
N |
Password |
nvarchar(50) |
N |
Description |
nvarchar(254) |
Y |
对应的XML,有一种形式如下(丢掉了nvarchar的长度)
<Users PrimaryKey="Id">
<Id AllowDBNull="False" SqlDbType="int"/>
<UserName AllowDBNull="False" SqlDbType="nvarchar"/>
<Password AllowDBNull="False" SqlDbType="nvarchar"/>
<Description AllowDBNull="True" SqlDbType="nvarchar"/>
</Users>
给上述XML变个形,加点料,看上去像个User 类
<User Table="Users" Set="Users" PrimaryKey="Id">
<Id Column="Id" DataType="System.Int32" AllowDBNull="False" SqlDbType="int"/>
<UserName Column="UserName" DataType="System.String" AllowDBNull="False" SqlDbType="nvarchar"/>
<Password Column="Password" DataType="System.String" AllowDBNull="False" SqlDbType="nvarchar"/>
<Description Column="Description" DataType="System.String" AllowDBNull="True" SqlDbType="nvarchar"/>
</User>
XF把整个<User>称之为ElementSchema,User称为ElementName。<Id>、<UserName>、<Password>和<Description>称之为FieldSchema,同样Id、UserName、Password和Description称为FieldName。<User>还有一个重要的属性Set,这里Set意为集合,而不是设置,同理把Users称之为SetName(集合名)。
当ColumnName与FieldName一样的时候,可以省略Column属性,因此,User类的XML,可以简化为:
<User Table="Users" Set="Users" PrimaryKey="Id">
<Id DataType="System.Int32" AllowDBNull="False" SqlDbType="int"/>
<UserName DataType="System.String" AllowDBNull="False" SqlDbType="nvarchar"/>
<Password DataType="System.String" AllowDBNull="False" SqlDbType="nvarchar"/>
<Description DataType="System.String" AllowDBNull="True" SqlDbType="nvarchar"/>
</User>
XF内置了PrefixSuffixNameMap和SingularPluralNameMap二个类,用来把数据库中的每个表(和视图)生成类XML。(还有Foreign key生成Relationship,后述)。这二个类都继承自NameMap类。
上述例子中,用到的就是SingularPluralNameMap。其构造函数为:
public SingularPluralNameMap(XElement nameMapConfig)
当以复数形式命名数据库表时,请使用改类。参数nameMapConfig用来修饰(按单复数规律)生成后的XML。
譬如某些名词单复数一样或者你喜欢取一个自己喜欢的名称。如有以下nameMapConfig:
<UserElement Table="Users" Set="UserSet">
<Descr Column="Description" />
</UserElement>
则最终User类XML如下:
<UserElement Table="Users" Set="UserSet" PrimaryKey="Id">
<Id DataType="System.Int32" AllowDBNull="False" SqlDbType="int"/>
<UserName DataType="System.String" AllowDBNull="False" SqlDbType="nvarchar"/>
<Password DataType="System.String" AllowDBNull="False" SqlDbType="nvarchar"/>
<Descr Column="Description" DataType="System.String" AllowDBNull="True" SqlDbType="nvarchar"/>
</UserElement>
PrefixSuffixNameMap 假定表名是单数,用来Prefix + TableName + Suffix来命名SetName,参数nameMapConfig见上。
它有如下二个构造函数:
public PrefixSuffixNameMap(XElement nameMapConfig, string prefix, string suffix)
// 相当 public PrefixSuffixNameMap(XElement nameMapConfig, string prefix="SetOf", string suffix=string.Empty)
public PrefixSuffixNameMap(XElement nameMapConfig)
使用该类,则最终User类XML如下:
<Users Table="Users" Set="SetOfUsers" PrimaryKey="Id">
<Id DataType="System.Int32" AllowDBNull="False" SqlDbType="int"/>
<UserName DataType="System.String" AllowDBNull="False" SqlDbType="nvarchar"/>
<Password DataType="System.String" AllowDBNull="False" SqlDbType="nvarchar"/>
<Description DataType="System.String" AllowDBNull="True" SqlDbType="nvarchar"/>
</Users>
数据库中不单有表(和视图),还有“关系”,二个表之间的关系,依赖Foreign key。同样,XF会把Foreign key以XML描述,称之为Relationship。
Relationship用到的名称均为ElementName和FieldName,而不是TableName和ColumnName。下图所示表间Foreign key:
会生成:
<Relationship From="Employee" To="Job" Type="ManyToOne" Content="Employee(JobId),Job(Id)"/>
<Relationship From="User" To="Employee" Type="ManyToOne" Content="User(EmployeeId),Employee(Id)"/>
<Relationship From="UserRole" To="Role" Type="ManyToOne" Content="UserRole(RoleId),Role(Id)"/>
<Relationship From="UserRole" To="User" Type="ManyToOne" Content="UserRole(UserId),User(Id)"/>
注:如果,你不喜欢在数据库中设置Foreign key,上面的那些Relationship,就需要通过DatabaseConfig或PrimaryConfig修饰(添加)到DatabaseSchema或PrimarySchema。
注:在生成PrimarySchema时,会自动(推导出)加上下列多对多的Relationship:
<Relationship From="Role" To="User" Type="ManyToMany" Content="Role(Id),UserRole(RoleId);UserRole(UserId),User(Id)"/>
注:在DatabaseConfig或PrimaryConfig(在PrimaryConfig更合适),还可以添加如下<ReferencePath>:
<ReferencePath Name=” User- Job” From="User" To="Job" Content="User(EmployeeId),Employee(Id);Employee(JobId),Job(Id)">
XF把二个及以上ManyToOne或OneToOne按ToOne方向串联起来称之为ReferencePath,一般地ReferencePath有一个Name属性,以方便引用(如ReferencePath.Name=” User- Job”)。ReferencePath提供二个表之间间接的关联。
至此DatabaseSchema初稿已经生成,如果还有要补充的内容,可通过DatabaseConfig(也可以通过PrimaryConfig)修饰。
DatabaseConfig典型应用就是为表(Table)中的一列(Column,通常为主键)指定序列(Sequence)。
如在DatabaseConfig中有如下片段:
……
<Employee>
<Id>
<Sequence>
<SequenceName>Sequence-Employees</SequenceName>
</Sequence>
</Id>
……
</Employee>
……
<User>
<Id>
<Sequence>
<SequenceName>Sequence-Users</SequenceName>
</Sequence>
</Id>
……
</User>
……
修饰后DatabaseSchema 相应片段为
……
<Employee Table="Employees" PrimaryKey="Id" Set="Employees" TableType="Table">
<Id DataType="System.Int32" AllowDBNull="False" Unique="True" ReadOnly="False" SqlDbType="int">
<Sequence>
<SequenceName>Sequence-Employees</SequenceName>
</Sequence>
</Id>
……
</Employee>
……
<User Table="Users" PrimaryKey="Id" Set="Users" TableType="Table">
<Id DataType="System.Int32" AllowDBNull="False" Unique="True" ReadOnly="False" SqlDbType="int">
<Sequence>
<SequenceName>Sequence-Users</SequenceName>
</Sequence>
</Id>
……
</User>
……
XF把作为子节点插入的Element称之为Attribute。实际也对应一个继承自Attribute的类。
以<Sequence>为例,对应:
public class SequenceAttribute : Attribute
{
public string SequenceName { get; private set; }
public SequenceAttribute(string sequenceName)
{
SequenceName = sequenceName;
}
}
注意与XAttribute的区别,如下XML片段,Table、PrimaryKey、Set、TableType都是XAttribute(属于User的),同样DataType、AllowDBNull、Unique、ReadOnly、SqlDbType也是(属于Id的)
<User Table="Users" PrimaryKey="Id" Set="Users" TableType="Table">
<Id DataType="System.Int32" AllowDBNull="False" Unique="True" ReadOnly="False" SqlDbType="int">
这些XAttribute,属于不可配置的数据库属性。方法解析Schema时,只会解析Attribute,而不会理会XAttribute。
XF另外还定义了一个PrimeAttribute类(标记类,无参构造函数,无属性),用于<Relationship>和<ReferencePath>标注首选项。
除了XF自己定义的二个Attribute类,还支持下列.NET Framework Attribute类:
(也支持System.ComponentModel.DataAnnotations.ValidationAttribute的子类,详见Chapter Data Validation,在此处不列出)
System.ComponentModel.DataAnnotations.KeyAttribute
System.ComponentModel.DataAnnotations.TimestampAttribute
System.ComponentModel.DataAnnotations.ConcurrencyCheckAttribute
System.ComponentModel.DefaultValueAttribute
System.ComponentModel.DisplayNameAttribute
System.ComponentModel.DataAnnotations.DisplayAttribute
一个真实的DatabaseSchema片段:
<User Table="Users" PrimaryKey="Id" Set="Users" TableType="Table">
<Id DataType="System.Int32" AllowDBNull="False" Unique="True" ReadOnly="False" SqlDbType="int">
<Key/>
<Sequence>
<SequenceName>Sequence-Users</SequenceName>
</Sequence>
</Id>
<EmployeeId DataType="System.Int32" AllowDBNull="False" Unique="False" ReadOnly="False" SqlDbType="int">
<Required/>
</EmployeeId>
<UserName DataType="System.String" AllowDBNull="False" Unique="True" ReadOnly="False" SqlDbType="nvarchar">
<Required/>
</UserName>
<Password DataType="System.String" AllowDBNull="False" Unique="False" ReadOnly="False" SqlDbType="nvarchar">
<Required/>
<DefaultValue>
<Value>a1b2c3</Value>
</DefaultValue>
</Password>
<Description DataType="System.String" AllowDBNull="True" Unique="False" ReadOnly="False" SqlDbType="nvarchar"/>
</User>
至此DatabaseSchema已完全生成,再经由PrimaryConfig修饰(Modify),就得到PrimarySchema。
如上所述,DatabaseConfig的内容,全都可以放在PrimaryConfig,DatabaseConfig甚至可以没有。DatabaseConfig的存在,是为了层次更清晰。除了这些PrimaryConfig还可以有哪些内容呢?PrimaryConfig的主要作用就是横向扩展Field。如有以下PrimaryConfig片段:
<User>
<Employee.Name Element="Employee" Field="Name" Relationship.Content="User(EmployeeId),Employee(Id)"/>
<Job.Name Element="Job" Field="Name" ReferencePath.Name=" User- Job"/>
<Job.Descr Element="Job" Field="Descr" ReferencePath.Name=" User- Job"/>
</User>
这里明确指出了Relationship或ReferencePath。在未指定的情况:
1.在所有包括<Prime>的Relationship和ReferencePath中,按 非多对多Relationship、多对多Relationship、ReferencePath查找;
2.在不包括<Prime>的Relationship和ReferencePath中,也按 非多对多Relationship、多对多Relationship、ReferencePath查找;
3.试图推导ReferencePath,(只用于ElementQuerier,见Chapter Querying Data)
修饰(Modify)后,会添加到<User>。这里不再列出修饰(Modify)后的XML。
至此,最主要的PrimarySchema已经生成(DatabaseSchema是个过渡,主要用来生成PrimarySchema)。
针对不同的应用场景,可能需要特定应用场景的PrimarySchema变体。XF通过NamedConfig
针对不同的应用,可能需要特定应用的PrimarySchema变体。XF通过NamedConfig对PrimarySchema修饰(Modify)得到这个变体,称之为NamedSchema。
顾名思义,NamedSchema 必定有一个名称,这个名称就是Name XAttribute属性,显然,这个Name属性来自NamedConfig。
一般地,会把所有的NamedConfig放在同一个目录下,XF会根据这些NamedConfig,生成每一个NamedConfig对应的NamedSchema。
在调用方法时,通过指定SchemaName来取得对应的Schema(不指定、SchemaName为null或空字符串会取得PrimarySchema)。
如果调用方法需要更具个性化,还可以提供一个方法级别的config,即modifying。来修饰上述Schema,形成本次方法调用的Schema。
Chapter Schema的更多相关文章
- Chapter Configuration
Chapter Configuration 在Web.config 或App.config的configuration节,插入如下配置: <configuration> …… <co ...
- Chapter Querying Data
Chapter Querying Data XF获取数据的三种方法: 其中参数schema,参见 Chapter Schema. 下面列出一个后面将会用到的schema片段,称之为片段A: <U ...
- XF 文档 - Element Framework Doc
配置篇 Chapter Configuration Schema篇 Chapter Schema 查询篇 Chapter Querying Data 数据更改及验证篇 Chapter Data Mod ...
- Chapter Data Modification & Chapter Data Validation
Chapter Data Modification XF的数据提交,支持单行.集合和多层次的master-details结构的数据. Create 当提交如下数据 <Job> <Id ...
- MongoDB:The Definitive Guide CHAPTER 2 Getting Started
MongoDB is very powerful, but it is still easy to get started with. In this chapter we’ll introduce ...
- Chapter 4: Spring and AOP:Spring's AOP Framework -- draft
Spring's AOP Framework Let's begin by looking at Spring's own AOP framework - a proxy-based framewor ...
- 复杂和遗留的数据库schema
本文作者:苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/50414652 In this chapter, we focus ...
- Professional C# 6 and .NET Core 1.0 - Chapter 42 ASP.NET Web API
本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处: -------------------------------------------------------- ...
- Professional C# 6 and .NET Core 1.0 - Chapter 38 Entity Framework Core
本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处:Professional C# 6 and .NET Core 1.0 - Chapter 38 Entity F ...
随机推荐
- eclipse修改工程名
直接修改工程可能会产生一些莫名其妙的问题,需遵循以下三步: 1. 右键工程:Refactor->Rename,或选中工程按F2,修改名称 2. 右键工程:Properties->Web P ...
- MSCRM Plugin Debug
MS CRM 2011的自定义和开发(11)——插件(plugin)开发(四) 上面几篇文章介绍了Microsoft Dynamics CRM 2011中如何进行插件开发,本文将介绍插件的调试. 调试 ...
- 【性能测试】性能测试总结<一>
目录: 一. 什么是软件性能 二.不同群体眼中的性能 三.性能测试类型 四.性能测试应用场景 五.性能测试基本概念 正文: 一. 什么是软件性能 定义:软件的性能是软件的一种非功能特性,它关注的不是软 ...
- 深入了解iPad上的MouseEvent【转】
iPad上没有鼠标,所以手指在触发触摸事件(TouchEvent)的时候,系统也会产生出模拟的鼠标事件(MouseEvent). 这对于普通网页的浏览需求而言,基本可以做到与PC端浏览器无明显 ...
- asp.net get App_Data 目录几种方法 path
方法一 //ASP.NET MVC1 -> MVC3 string path = HttpContext.Current.Server.MapPath("~/App_Data/some ...
- Centos7和win7双系统调整默认启动
centos7之后都上grub2了,所以你要更改默认启动项什么的就不能像以前一样去改 /etc/grub.conf 当然你更不能去改/etc/grub2.conf 上了grub2之后,在设计有意规避让 ...
- 设计模式的一些杂谈与反思---functionn和signals
以下关于GOF的一些例子命名不是很准确,但是大概意思差不多,懒得再去翻书了 模拟观察者模式 模拟中介者模式 模拟command模式 模拟memento和command 模拟观察者模式 观察者与职责 ...
- c/c++多线程编程中最好不要加volatile
来自https://www.zhihu.com/question/31459750 答主解释说:不能指望volatile能解决多线程竞争问题,除非所用的环境系统不可靠才会为了保险加上volatile, ...
- "XX cannot be resolved to a type "eclipse报错及解决说明
转自:http://zhaoningbo.iteye.com/blog/1137215 引言: eclipse新导入的项目经常可以看到“XX cannot be resolved to a type” ...
- 判断apache是否启动的脚本
#!/bin/bashhttp=$(netstat -tunpl | awk '{printf $4 "\n"}' | grep '80$')if [ -z "$http ...