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的更多相关文章

  1. java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

    org.springframework.dao.TransientDataAccessResourceException: ### Error updating database. Cause: ja ...

  2. 执行update操作的话,就会报“Connection is read-only. Queries leading to data modification are not allowed”的异常。

    我用的是 spring + springmvc + mybatis +mysql. <tx:advice id="txAdvice" transaction-manager= ...

  3. Connection is read-only. Queries leading to data modification are not allowed

    看了下mysql-connector-5.1.40版本中,如果设置failoverReadOnly=true (即默认值,参考链接),当mysql连接failover时,会根据jdbc连接串将当前连接 ...

  4. 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 描述:框架注入时候,配置了事物管理,权限设置 ...

  5. [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 ...

  6. Datasets for Data Mining and Data Science

    https://github.com/mattbane/RecommenderSystem http://grouplens.org/datasets/movielens/ KDDCUP-2012官网 ...

  7. 【转】浏览器中的data类型的Url格式,data:image/png,data:image/jpeg!

    所谓"data"类型的Url格式,是在RFC2397中 提出的,目的对于一些"小"的数据,可以在网页中直接嵌入,而不是从外部文件载入.例如对于img这个Tag, ...

  8. 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. ...

  9. 初探 spring data(一)--- spring data 概述

    由于自己一个项目要用多到Sql与NoSql两种截然不同的数据结构,但在编程上我希望统一接口API,让不同类型的数据库能在相同的编程接口模式下运作.于是找了一个spring的官网,发现一个spring ...

随机推荐

  1. CCS float vs clear

    有人已经写过了.(*^__^*) 嘻嘻…… 为啥我不能写, ( ‵o′)凸 float 首先,HTML的布局是流布局.其元素是分为行内元素和块级元素的. 所谓行内元素就是接着写不会发生换行的元素如&l ...

  2. [原]Fedora 20的yum配置

    新装了一套Fedora 20操作系统,又要开始配置yum了.下面总结以下步骤: 1.下载国内比较快的yum源 推荐163的yum源,sohu的yum源也不错,我一般就装第一个,安装163 yum源主页 ...

  3. HackerRank "Training the army" - Max Flow

    First problem to learn Max Flow. Ford-Fulkerson is a group of algorithms - Dinic is one of it.It is ...

  4. POJ #1141 - Brackets Sequence - TODO: POJ website issue

    A bottom-up DP. To be honest, it is not easy to relate DP to this problem. Maybe, all "most&quo ...

  5. php PDO连接数据库

    [PDO是啥] PDO是PHP 5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接和处理,什么 php_mysql.dll.php_pgsql.d ...

  6. 战胜忧虑<1>——不要让忧郁侵入你的生活

    1.不要让忧郁侵入你的生活. 备注:忧郁:一种情绪与心理状态,指一个人呈现哀伤.心情低落的状况,绝望与沮丧为其特色. 解决方法:奥斯勒博士说的那样:用铁门把过去和未来隔断,生活在完全独立的今天. 现在 ...

  7. sgu233 little kings

    题目大意: 有n*n的棋盘上放k个国王.国王可以攻击与它相邻的八个格子.现在要使国王不相互攻击,有多少种放置的方案数.一个格子不能放两个国王. n<=10,k<=n*n. 分析:简单的状态 ...

  8. nginx 出现 13: Permission denied

    原文地址:http://www.nginx.cn/695.html 前段时间把程序员的wordpress升级到3.5.1,本身如果没有特别的插件,在后台更新就能完成. 更新完成后在后台发布文章,编辑器 ...

  9. (二)java特征

    java的核心是面向对象,与之相对的是面向过程的编程,在对整个java编程没有足够的理解和运用的情况下恐怕没办法很好的理解这两个概念.     在我的初步理解中,写一个程序就例如做一件事情,面向过程的 ...

  10. Wordpress-数据库结构分析(转)

    之前用了一段时间的Wordpress,觉得真的是一个优秀的博客系统,而且有大量的主题和插件.是我目前用过的最棒的一个博客平台.不仅如此,Wordpress 的代码也是写得非常漂亮,很适合用来学习PHP ...