表示层简单的验证,我们可以使用基于对象属性内容的验证。在NHibernate Contributions中有一个可用的项目NHibernate.Validator。可以通过SVN下载NHibernate Contribution项目的源代码:地址是https://nhcontrib.svn.sourceforge.net,也可以通过NuGet获得。

配置验证器

一旦在解决方案中引用了NHibernate.Validator程序集,我们就需要配置验证引擎。为此,该项目定义了一个fluent API。首先,我们必须定义一个验证器配置的实例,如下面的代码所示:

var nhvConfig =new NHibernate.Validator.Cfg.Loquacious.FluentConfiguration();

注意这跟NHibernate配置不一样。

现在可以使用fluent API配置前面的配置对象和定义:

  • 我们想使用哪个验证模式
  • 可以在哪里找到验证定义
  • 如何将验证和NHibernate整合
nhvConfig.SetDefaultValidatorMode(ValidatorMode.UseAttribute).Register(typeof(Product).Assembly.ValidationDefinitions()).IntegrateWithNHibernate.ApplyingDDLConstraints().And.RegisteringListeners();

在上面的代码中,我们使用特性定义验证规则。还指示验证引擎解析我们定义的实体程序集。最后,请求验证引擎使用元信息应用到模型来丰富架构定义(调用ApplyDDLConstraints),还请求它定义两个使用NHibernate的截获器,无论何时插入或更新实体时都透明的验证属性(调用RegisteringListeners)。

有了这个验证配置,就可以创建验证引擎对象并使用前面的配置对象配置它了。如下面的代码所示:

var validatorEngine = new ValidatorEngine();
validatorEngine.Configure(nhvConfig);

最后为NHibernate配置对象使用由NHibernate.Validator项目定义的Initialize扩展方法。验证引擎对象作为Initialize方法的参数,如下面的代码所示:

nhibernateConfig.Initialize(validatorEngine); 

在所有设置之后,我们准备创建或重新创建数据库架构,使用NHibernate的SchemaExport类,如下面的代码所示:

new SchemaExport(c).Execute(false, true, false); 

定义验证规则

完成了系统的配置和数据库架构的创建,就可以使用特性声明实体了。

每个特性都定义有一个Message参数,用于验证失败时显示的信息。最常用的一个特性还有NotNull,表示属性不能为空。一个产品必须有一个合法的名字,如下面的代码所示:

[NotNull(Message = "Product must have a valid name")]
public string Name { get; set; }

通常,Product实体的Name必须至少有一个或两个且不超过50个字符。我们可以使用Length特性验证:

[NotNull(Message = "Product must have a valid name")]
[Length(Min = 2, Max = 50, Message = "Name of product must be between 1 and 50 char")]
public string Name { get; set; }

如上面的例子,我们可以在一个属性上定义多个特性。

Fluent方式配置验证规则

如果不想在模型的属性上使用特性验证,我们可以使用NHibernatevalidator提供的fluent API配置实体的验证。

为我们想验证的每个实体定义一个继承自ValidationDef<T>的类,T表示我们想验证的实体。如果想验证Product实体,我们可以定义下面的类:

public class ProductValidator : ValidationDef<Product>
{ }

在上面类的构造函数中,我们使用NHibernate.Validator提供的fluent API以声明方式定义实体的验证逻辑。获得和前面的例子中相同的结果,我们可以使用下面的代码:

public ProductValidator()
{Define(x => x.Name).NotNullable().WithMessage("The product name cannot be undefined").And.LengthBetween(2, 50).WithMessage("Product name must be between 2 and 50 char");
}

执行验证

配置验证器的时候,我们注册了两个NHibernate监听器,当实体插入或更新时就会触发它们。如果实体处于不合法的状态,监听器就会抛出异常。

通常,我们不希望在验证失败时抛出异常。好点的解决方案就是在保存或更新实体之前就验证它们。如下面的代码所示:

var product = new Product {...};
var validator = new ValidatorEngine();
var invalidValues = validator.Validate(product);
if (invalidValues.Length > 0)ShowInvalidValues(product, invalidValues);
elsesession.Save(product);

上面的代码中,我们创建了一个product实体,然后使用验证引擎验证product。验证方法返回InvalidValue对象的数组。如果产品合法,数组的长度为0,否则数组的每个元素包含验证失败的信息。如果验证成功了,我们只保存产品,否则显示出验证失败的信息,如下面的代码所示:

private static void ShowInvalidValues(object entity, IEnumerable<InvalidValue> invalidValues)
{Console.WriteLine(entity.GetType().Name);foreach (var invalidValue in invalidValues)Console.WriteLine(" Property {0}: {1}",invalidValue.PropertyName,invalidValue.Message);
}

下面我们完成一个例子。

使用属性验证

在这个例子中,我们想实现一个简单的模型,通过在属性上声明来验证。

1. 在MMSM中创建一个空数据库:BasicValidationSample。

2. 在Visual Studio中,创建一个控制台应用程序:BasicValidtionSample,并设置项目的Target framework为.NET Framework 4.0。

3. 添加对Castle.Core.dll, FluentNHibernate.dll,Iesi.Collections.dll, NHibernate.dll, NHibernate.ByteCode.Castle.dll程序集的引用,NHibernate.Validator我们通过NuGet添加。

4. 在Solution Explorer中,右击References文件夹,选择"Add Library Package Reference…"(在我的电脑上是Manage NuGet Packages),在弹出的对话框中,在左边选择Online,然后在搜索框中输入NHibernate.Validator,然后安装即可,如下图所示:

5. 在项目中添加一个Category类,如下所示:

public class Category
{public virtual Guid Id { get; set; }[NotNullNotEmpty(Message = "The category name cannot be undefined.")][Length(Min = 2, Max = 50, Message ="The category name must be between 2 and 50 characters long")]public virtual string Name { get; set; }
}

Category的Name属性不能为空,且长度在2到50之间。

6. 添加Category的映射类CategoryMap,如下面的代码所示:

public class CategoryMap : ClassMap<Category>
{public CategoryMap(){Id(x => x.Id).GeneratedBy.GuidComb();Map(x => x.Name);}
}

7. 在项目中添加一个Product类,代码如下所示:

public class Product
{public virtual Guid Id { get; set; }public virtual string Name { get; set; }[NotNull]public virtual Category Category { get; set; }[NotNull]public virtual decimal UnitPrice { get; set; }[NotNull][Min(1, Message = "Units on stock must be a positive number.")]public virtual int UnitsOnStock { get; set; }[NotNull][Min(1, Message = "Reorder level must be a positive number.")]public virtual int ReorderLevel { get; set; }[NotNull]public virtual bool Discontinued { get; set; }
}

Category,UnitPrice,UnitsOnStock,ReorderLevel,Discontinued都不能为空,UnitsOnStock和ReorderLevel必须是正数。

8. 添加Product的映射类ProductMap,代码如下所示:

public class ProductMap : ClassMap<Product>
{public ProductMap(){Id(x => x.Id).GeneratedBy.GuidComb();Map(x => x.Name);References(x => x.Category);Map(x => x.UnitPrice);Map(x => x.UnitsOnStock);Map(x => x.ReorderLevel);Map(x => x.Discontinued);}
}

9. 在Program类中定义一个连接字符串,如下面的代码所示:

const string connString ="server=.;database=BasicValidationSample;" +"integrated security=true";

10. 在Program类中的Main方法中,使用Fluent NHibernate的API创建一个session工厂,代码如下所示:

static void Main(string[] args)
{var factory = Fluently.Configure().Database(MsSqlConfiguration.MsSql2008.ConnectionString(connString).ShowSql()).Mappings(m => m.FluentMappings.AddFromAssemblyOf<Product>()).ExposeConfiguration(ExportSchema).BuildSessionFactory();Console.Write("Hit enter to exit:");Console.ReadLine();
}

11. 我们需要实现上面代码中由ExposeCofiguration方法调用的ExportSchema方法。在这个方法中,我们配置验证引擎,然后使用这个验证其配置初始化NHibernate配置,如下面的代码所示:

private static void ExportSchema(Configuration c)
{var nhvConfig = new NHibernate.Validator.Cfg.Loquacious.FluentConfiguration();nhvConfig.SetDefaultValidatorMode(ValidatorMode.UseAttribute).Register(typeof(Product).Assembly.ValidationDefinitions()).IntegrateWithNHibernate.ApplyingDDLConstraints().And.RegisteringListeners();var validatorEngine = new ValidatorEngine();validatorEngine.Configure(nhvConfig);ValidatorInitializer.Initialize(c, validatorEngine);new SchemaExport(c).Execute(true, true, false);
}

在上面的例子中,我们通过NuGet快速添加了NHibernate.Validator.dll程序集,然后在我们的实体上声明了验证特性,最后配置NHibernate使用验证引擎在持久化到数据库之前验证实体。

转载于:https://www.cnblogs.com/nianming/archive/2011/11/28/2266721.html

NHibernate初学者指南(18):验证单个属性相关推荐

  1. NHibernate初学者指南(15):使用LINQ to NHibernate提供程序查询数据

    在前面的<NHibernate初学者指南(8):增删查改>一文中简单的提到了查询一个实体的Get<T>和Load<T>方法以及查询实体列表的Query<T&g ...

  2. NHibernate初学者指南(10):一级和二级缓存

    一级缓存 为了获得更好的性能,NHibernate智能地缓存数据.NHibernate有不同的缓存机制起作用,最重要的就是一级缓存.每个session对象维持一个一级缓存,session对象创建时缓存 ...

  3. NHibernate初学者指南(1):开篇

    这个系列所有的文章都是根据NHibernate 3 Beginner's Guide一书完成的,主要记录自己的学习经历,方便以后的查阅.鉴于<Entity Framework 4 in Acti ...

  4. NHibernate初学者指南(2):一个完整的例子

    准备开发环境 操作系统:Windows Vista, Windows 7, Windows Server 2003 或 Windows Server 2008 IDE:VS 2010 Professi ...

  5. NHibernate初学者指南(6):映射模型到数据库之方式二

    使用Fluent NHibernate自动映射 使用Fluent NHibernate自动映射,首先要将映射的实体放到一个命名空间中,这使得通知AutoMapper哪些实体和值对象包含在映射中更容易. ...

  6. python编程电子书下载-python编程初学者指南

    python编程初学者指南全书共12章,内容浅显易懂,书中的每一个章节都会用一个完整的游戏来演示其中的关键知识点,最后都会对该章的知识点进行小结,还会给出一些小练习让你试试身手.东坡小编为大家分享py ...

  7. python编程入门指南上下百度云-Python编程初学者指南 PDF扫描版[87MB]

    Python编程初学者指南 内容简介: 如果你刚刚接触Python编程,而且正在寻找一本实用的教程,那么这本书为你量身打造.通过阅读本书,你不仅会学到很多实用的Python编程知识,还将懂得如何在实际 ...

  8. java初学者指南_Java代理初学者指南

    java初学者指南 尽管Java初学者很快学会了键入public static void main来运行他们的应用程序,但是即使是经验丰富的开发人员也常常不知道JVM对Java流程的两个附加入口点的支 ...

  9. 初学者指南:什么是算法?11行伪代码给你讲明白

    导读:本文带你熟悉一个重要的术语--算法. 作者:帕诺斯·卢里达斯(Panos Louridas) 来源:大数据DT(ID:hzdashuju) 算法(algorithm)就是一个过程,是一种特殊的过 ...

  10. css网格_CSS网格初学者指南

    css网格 by Kara Luton 卡拉·卢顿(Kara Luton) CSS网格初学者指南 (A Beginner's Guide to CSS Grid) I first heard abou ...

最新文章

  1. Mac 升级系统 pod 命令无效
  2. windows下mysql开启慢查询
  3. 数字证书应用综合揭秘(包括证书生成、加密、解密、签名、验签)
  4. mysql jdbc dbcp_连接数据库 JDBC、DBCP、JNDI
  5. 详解MySQL字符串函数重复REPEAT()、反转REVERSE()、格式化FORMAT()、返回空格SPACE()函数用法(四)
  6. 计算机显卡是指什么时候,电脑哪个是显卡
  7. 分号可以用来分段么_更高效的GMX分段模拟方法:修改tpr文件
  8. 电气自动化c语言用什么软件,电气自动化需要哪些高级语言?
  9. 《深入理解Java虚拟机》第5章 调优案例分析与实战
  10. Unity 移动端的复制这么写
  11. linux资源管理器编写,Linux系统资源管理器.doc
  12. SSH框架之文件上传
  13. RS触发器、D触发器、JK触发器、T,T‘触发器的功能详细总结
  14. 启用计算机的快捷键,电脑开机启动项选择快捷键大全
  15. 尚学堂Spring视频教程(七):AOP XML
  16. 将图片(HDC)打印出来
  17. Android Service之bindService
  18. 使用itext将HTML 生成PDF文件
  19. 1Mbps带宽到底能够达到什么效果,看看下面的介绍就懂了。
  20. CV之Face Change:基于人工智能实现国内众多一线美女明星换脸(基于Face++输出4*106个特征点定位+融合代码、deepfake技术)

热门文章

  1. ubuntu mysql 5.7 出错_ubuntu mysql5.7 启动提示错误:/var/run/mysqld/mysqld.sock
  2. OpenCV---直线检测
  3. Linux DRM KMS 驱动简介
  4. C++中list的各种使用
  5. C - Catch That Cow POJ - 3278(广搜)
  6. 作为Scala语法糖的设计模式
  7. hdu1166------树状数组(板子)
  8. 区块链的概念是由()于2008年提出_区块链,下一个时代的基础设施
  9. apache 支持.htaccess 解决Internal Server Error The server 错误
  10. [个人笔记] 关于linux的常见问题合集