Chapter Data Modification & Chapter Data Validation
Chapter Data Modification
XF的数据提交,支持单行、集合和多层次的master-details结构的数据。
Create
当提交如下数据
<Job>
<Id/>
<Name>CEO</Name>
<Allowance>1000</Allowance>
<Descr/>
</Job>
Create方法在数据库表Jobs中插入一条返回数据。注意,提交的数据中没有提供Id的值,
表示Id字段为自增长或取自序列Sequence值(在schema Field <Id>指定)。
也可以在提交数据中设置Id的值,显然,对于自增长字段,设置了也无效,但会优先于序列Sequence,也就是,设置了Id的值,就不会去序列取值了。
多层master-details举例:
<Job>
<Id/>
<Name>Clerk</Name>
<Allowance>0</Allowance>
<Descr/>
<Employees>
<Employee>
<Id/>
<Name>John Smith</Name>
<Users>
<User>
<Id/>
<UserName>John</UserName>
</User>
</Users>
</Employee>
<Employee>
<Id/>
<Name>Michael Gill</Name>
<Users>
<User>
<Id/>
<UserName>Gill</UserName>
</User>
</Users>
</Employee>
</Employees>
</Job>
同样,方法结束,所有的Id值都会填入。
多对多:
<User>
<Id/>
<UserName>Carl</UserName>
<Roles>
<Role>
<Id>1</Id>
...
</Role>
<Role>
<Id>2</Id>
...
</Role>
</Roles>
</User>
同样符合多对多“短路”规则,如果<Role>再内嵌一个集合(Set),将被丢弃。
提交数据如果存在计算字段或外表字段(如:<Job.Name>CTO</Job.Name>),将被丢弃。
Delete
XF在删除master-details结构的details时,与EF一样,会根据schema中detail的关系字段(外键字段)是否为空,来决定是删除行,还是设置关系字段为空。
例如:
<Job>
...
<Employees>
<Employee>
...
</Employee>
...
</Employees>
</Job>
如果Employees表中字段JobId允许为空,不是Delete Employees…,而是Update Set JobId = NULL…,因此,Delete方法会触发Updating事件。
Update
在Update master-details结构的数据时,相当于“Put”。
如通过并发检查,Update会强制同步数据库相应的数据行为提交数据,也就是说对于details,会和数据库相应数据进行比较,
如果数据库中不存在就Insert,反之就是Update,数据库存在而提交数据中不存在的则删除。因此,不但会触发Updating事件,也可能触发Inserting、Inserted和Deleting事件。
UpdateUpdateWithOriginal
考虑一个典型的Update场景,首先获取需要编辑的(层次master-details)原始数据,然后(一般有个UI)进行修改,
最后把修改完的数据提交保存(上述Update方法)。如果,不光提交修改后的数据还把开始获取的原始数据一并提交,
就需要用到UpdateUpdateWithOriginal,这里的Original就是指原始数据。
与Update方法类似,不同的是UpdateUpdateWithOriginal比较的数据不再是数据库中的数据,而是Original。
事务包
所谓事务包就是把一系列方法调用打包在一个<Transaction>里面,这一系列方法在同一事务内执行。
XF用ElementContext.SaveChanges(XElement packet)方法保存事务包。
事务包举例如下:
<Transaction>
<Create Schema="Membership">
<Users>
<User>
...
</User>
</Users>
</Create>
<Delete>
<Role>
...
</Role>
</Delete>
<Update Schema="Membership" Config="Staff">
<Config Name="Staff" Version="1.2.3">
...
</Config>
<Employee>
...
</Employee>
<Employee Original="True">
...
</Employee>
</Update>
</Transaction>
<Create Schema="Membership"> 指定使用名为Membership的NamedSchema
<Update Schema="Membership" Config="Staff"> 指定使用名为Membership的NamedSchema,并且内嵌一个Name为Staff的modifying schema。
<Employee Original="True"> 指出调用的是UpdateWithOriginal。调用Update方法,不需要<Employee Original="True">。
事务
上述方法都会自己管理事务。如果业务足够复杂,要编写代码启动事务,需按下列示意代码编写:
ElementContext elementContext = ...;
elementContext.Database.Connection.Open();
elementContext.Database.Transaction = elementContext.Database.Connection.BeginTransaction();
try
{
...
elementContext.Database.Transaction.Commit();
}
catch
{
elementContext.Database.Transaction.Rollback();
throw;
}
finally
{
elementContext.Database.Connection.Close();
elementContext.Database.Transaction = null;
}
并发
XF与EF一样,通过下面2个Attribute来控制(数据库行)并发:
TimestampAttribute
ConcurrencyCheckAttribute
在Delete或Update每个数据库行时,会检查上述2个Attribute标记的字段的值和数据库当前值是否一致,如不一致,则抛出ConcurrencyCheckException异常。
事件
ElementContext有四个事件:
Inserting 在插入数据行时发生,
事件参数的Node属性,就是将要插入数据库的行数据。这时还未插入数据库,是最后修改Node的机会。下面~ing事件同。
Inserted 在插入数据行后发生
事件参数的Node属性,是插入数据库后的行数据。这时自增长或取自序列的Id,已经回插到Node中。
事件参数的After属性,允许添加一组Sql,在插入后执行。相当数据库的After行触发器。
Deleting 在删除数据行时发生
事件参数的Before属性,相当数据库的After行触发器。
Updating 在更改数据行时发生
事件参数有After、Before属性。
Chapter Data Validation
在每个Element提交数据库前,都会对其验证,验证失败时,抛出ElementValidationException异常(内部封装ElementValidationResult[])。
当然,也可以调用ElementContext.GetValidationResults(…)来返回ElementValidationResult[],不提交数据库而直接验证。
XF验证完全仿照EF,支持下列Attribute,均继承自System.ComponentModel.DataAnnotations.ValidationAttribute:
CustomValidationAttribute
DataTypeAttribute
RangeAttribute
RegularExpressionAttribute
RequiredAttribute
StringLengthAttribute
MaxLengthAttribute
MinLengthAttribute
CreditCardAttribute
EmailAddressAttribute
PhoneAttribute
UrlAttribute
也可能会用到(如果配置的话):
DisplayNameAttribute
DisplayAttribute
在EF中,典型的类定义:
public class User
{
[Key]
public int Id { get; set; }
[DisplayName("用户名")]
[Required(AllowEmptyStrings = true)]
[MinLength(6)]
public string UserName { get; set; }
[DisplayName("密码")]
[Required(AllowEmptyStrings = true)]
[MinLength(6)]
public string Password { get; set; }
...
}
XF相应的配置(在schema中)如下:
<User Set="Users">
<Id>
<key/>
</Id>
<UserName>
<DisplayName>
<DisplayName>用户名</DisplayName>
</DisplayName>
<Required>
<AllowEmptyStrings>True</AllowEmptyStrings>
</Required>
<MinLength>
<Length>4</Length>
</MinLength>
</UserName>
<Password>
<DisplayName>
<DisplayName>密码</DisplayName>
</DisplayName>
<Required>
<AllowEmptyStrings>True</AllowEmptyStrings>
</Required>
<MinLength>
<Length>6</Length>
</MinLength>
</Password>
…
</User>
注:SQL Server 需设置<AllowEmptyStrings>True</AllowEmptyStrings>
除此之外,事件ElementContext.Validating 也会在验证Element时发生。
ValidationAttribute不足以应付的复杂或特殊的业务规则可以在此通过写代码来验证,
在事件参数ValidatingEventArgs中的ValidationResults添加未通过验证的ValidationResult。
Chapter Data Modification & Chapter Data Validation的更多相关文章
- java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
org.springframework.dao.TransientDataAccessResourceException: ### Error updating database. Cause: ja ...
- 执行update操作的话,就会报“Connection is read-only. Queries leading to data modification are not allowed”的异常。
我用的是 spring + springmvc + mybatis +mysql. <tx:advice id="txAdvice" transaction-manager= ...
- Connection is read-only. Queries leading to data modification are not allowed
看了下mysql-connector-5.1.40版本中,如果设置failoverReadOnly=true (即默认值,参考链接),当mysql连接failover时,会根据jdbc连接串将当前连接 ...
- java最全的Connection is read-only. Queries leading to data modification are not allowed
Connection is read-only. Queries leading to data modification are not allowed 描述:框架注入时候,配置了事物管理,权限设置 ...
- [Done]java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed ...
- Datasets for Data Mining and Data Science
https://github.com/mattbane/RecommenderSystem http://grouplens.org/datasets/movielens/ KDDCUP-2012官网 ...
- 【转】浏览器中的data类型的Url格式,data:image/png,data:image/jpeg!
所谓"data"类型的Url格式,是在RFC2397中 提出的,目的对于一些"小"的数据,可以在网页中直接嵌入,而不是从外部文件载入.例如对于img这个Tag, ...
- SQL data reader reading data performance test
/*Author: Jiangong SUN*/ As I've manipulated a lot of data using SQL data reader in recent project. ...
- 初探 spring data(一)--- spring data 概述
由于自己一个项目要用多到Sql与NoSql两种截然不同的数据结构,但在编程上我希望统一接口API,让不同类型的数据库能在相同的编程接口模式下运作.于是找了一个spring的官网,发现一个spring ...
随机推荐
- final,static
如果输入参数在方法体执行过程中,强制不能被修改,那么参数类型前加final比较安全. final修饰的函数会被编译器优化,优化意味着编译器可能将该方法用内联(inline)方式载入.final修饰变量 ...
- Java小陷阱
基本数据类型与字符串的连接 在Java中,+不仅可作为加法运算符使用,还可作为字符串连接运算符使用. 当把任何基本数据类型的值与字符串值进行连接运算时,基本类型的值将自动类型转换为字符串类型. pub ...
- WAS8.5安装
由于公司网络禁止上传图片,在网上找到相近的,安装过程图,可参照:http://www.open-open.com/doc/view/488fe6eaa2084da6b87cc18f1c00d2a8 1 ...
- CCS float vs clear
有人已经写过了.(*^__^*) 嘻嘻…… 为啥我不能写, ( ‵o′)凸 float 首先,HTML的布局是流布局.其元素是分为行内元素和块级元素的. 所谓行内元素就是接着写不会发生换行的元素如&l ...
- (zt)Lua的多任务机制——协程(coroutine)
原帖:http://blog.csdn.net/soloist/article/details/329381 并发是现实世界的本质特征,而聪明的计算机科学家用来模拟并发的技术手段便是多任务机制.大致上 ...
- 关于 Android导出apk时碰到的[Unable to execute dex: Multiple dex files define]
这是一个编译错误,在ADT的编译器和SDK的工具有差异或是版本不一致时常会出现的一个问题,解决的方案如下: 第一步: updated eclipse (Help->Check for updat ...
- 剑指offer系列53---字符串转化成整数
[题目]将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数 * []整数(32位)最大值:0X7fff ffff( 0111 1111 1111 1111 1111 1111 1111 1 ...
- NodeJS的异步编程风格
NodeJS的异步编程风格 http://www.infoq.com/cn/news/2011/09/nodejs-async-code NodeJS运行环境因其支持Javascript语言和异步编程 ...
- java和C++在多态实现上的区别
1:java中没有虚函数的概念,但是有抽 象函数的概念,用abstract关键字表示,java中抽象函数必须在抽象类中,而且抽象 函数不能有函数体,抽象类不能被实例化,只能由其子类实现抽象函数,如果某 ...
- IGS_学习笔记09_IREP生成服务后台工具Soagenerate.sh
2015-01-06 Created By BaoXinjian 参考:张礼军 - http://oracleseeker.com/2009/10/23/irep_service_generation ...