使用NHibernate 3.2实现Repository(ORuM)(十二)Repository、LINQ

mac2022-06-30  22

接NHibernate 3.2实现Repository(ORuM)前文

使用NHibernate-->NHibernate.Linq-->Linq,结合NHibernate和LINQ的优势,使Repository的对象持久化和对象查询两方面兼优,实现了鱼和熊掌兼得。 

使用LINQ重构Repository

修改Repository接口,使用LINQ减少方法,查询方法只有Query<TEntity>()。

using System;using System.Collections.Generic;using System.Linq;namespace MVCQuick.Framework.Repository{public interface IRepository : IDisposable { void Save<TEntity>(TEntity entity) where TEntity : EntityBase; void Update<TEntity>(TEntity entity) where TEntity : EntityBase; void SaveOrUpdate<TEntity>(TEntity entity) where TEntity : EntityBase; void Delete<TEntity>(TEntity entity) where TEntity : EntityBase; TEntity Get<TEntity>(int id) where TEntity : EntityBase; IQueryable<TEntity> Query<TEntity>(); ITransaction BeginTransaction(); }}

NHibernate 实现

using System;using System.Collections.Generic;using System.Linq;using NH = NHibernate;using NHibernate.Linq;namespace MVCQuick.Framework.Repository.NHibernate{ public class NHibernateRepository : IRepository {private NH.ISession session;private bool useNHibernateManager = true;public NHibernateRepository() { }public NHibernateRepository(NH.ISession session) {this.session = session;this.useNHibernateManager = false; }public NH.ISession Session {get {if (!useNHibernateManager) {return session; }else {return NHibernateManager.GetCurrentSession(); } } }public void Save<TEntity>(TEntity entity) where TEntity : EntityBase { NH.ISession session = Session; session.Save(entity); session.Flush(); }public void Update<TEntity>(TEntity entity) where TEntity : EntityBase { NH.ISession session = Session; session.Update(entity); session.Flush(); }public void SaveOrUpdate<TEntity>(TEntity entity) where TEntity : EntityBase { NH.ISession session = Session; session.SaveOrUpdate(entity); session.Flush(); }public void Delete<TEntity>(TEntity entity) where TEntity : EntityBase { NH.ISession session = Session; session.Delete(entity); session.Flush(); } public TEntity Get<TEntity>(int id) where TEntity : EntityBase { NH.ISession session = Session;return session.Get<TEntity>(id); } public IQueryable<TEntity> Query<TEntity>() { NH.ISession session = Session;return session.Query<TEntity>(); }public ITransaction BeginTransaction() { NH.ISession session = Session;return new NHibernateTransaction(session); }public void Dispose() {if (this.session != null) {this.session.Flush(); CloseSession(); } } private void CloseSession() { session.Close(); session.Dispose(); session = null; } }}

 

AutoMapping部分代码见以前文章。

Repository成效

寥寥几行代码就实现了一个复杂的数据存储层,似乎不可思议,那就看看使用效果如何。

1、定义实体类

 

Entities.cs using System;using System.Collections.Generic;namespace MVCQuick.Framework.Tests{public class Album : EntityBase {public string Title { get; set; }public decimal Price { get; set; } public string AlbumArtUrl { get; set; }public Genre Genre { get; set; }public Artist Artist { get; set; }public void Add() { } }public class Genre : EntityBase {public string Name { get; set; }public string Description { get; set; }public IEnumerable<Album> Albums { get; set; } }public class Artist : EntityBase {public string Name { get; set; }public Address Address { get; set; }public IEnumerable<Album> Albums { get; set; }public IDictionary<String, String> Settings { get; set; } }public class User : EntityBase {public string Username { get; set; }public string Email { get; set; }public string Password { get; set; }public IEnumerable<Role> Roles { get; set; }public User() { Roles = new List<Role>(); } }public class Role : EntityBase {public string Name { get; set; }public string Description { get; set; }public IEnumerable<User> Users { get; set; }public Role() { Users = new List<User>(); } }public class Address : IValueObject {public string City { get; set; }public string Country { get; set; }public string State { get; set; }public string Street { get; set; }public string Zip { get; set; } }}

2、CRUD

IRepository repository = new NHibernateRepository(); User user = new User { Username = "admin", Email = "admin@163.com", Password = "admin123" }; repository.Save(user); user = repository.Get<User>(1); user.Password = "123456"; repository.Update(user); user = repository.Get<User>(1); repository.Delete(user);

3、Transaction

IRepository repository = new NHibernateRepository(); var Users = new List<User>        {            new User { Username = "刘备" , Email = "lb@123.com", Password = "123456" },            new User { Username = "曹操" , Email = "cc@123.com", Password = "123456"  },            new User { Username = "孙权" , Email = "sq@123.com", Password = "123456"  },            new User { Username = "曹植" , Email = "cz@123.com"},            new User { Username = "曹丕" , Email = "cp@123.com"},            new User { Username = "张飞" },            new User { Username = "关羽" },            new User { Username = "赵云" }        };        ITransaction unitOfWork = repository.BeginTransaction();         foreach (var u in Users)        {            repository.Save(u);        }         unitOfWork.Commit();

4、Query

IList<User> users; User user = null; users = repository.Query<User>() .ToList<User>(); Assert.AreEqual(users.Count, 8);//Where users = repository.Query<User>() .Where(x => x.Username == "刘备").ToList<User>(); Assert.AreEqual(users.Count, 1); Assert.AreEqual(users[0].Username, "刘备");//OrderBy users = repository.Query<User>() .OrderByDescending(x => x.Id).ToList(); Assert.AreEqual(users[0].Username, "赵云");//Skip, Take users = repository.Query<User>() .Skip(1 * 3).Take(3).ToList(); Assert.AreEqual(users.Count, 3); Assert.AreEqual(users[0].Username, "曹植");//SingleOrDefault user = repository.Query<User>() .SingleOrDefault(x => x.Username == "刘备"); Assert.IsNotNull(user); Assert.AreEqual(user.Username, "刘备"); user = repository.Query<User>() .SingleOrDefault(x => x.Username == "诸葛亮"); Assert.IsNull(user); user = repository.Query<User>() .Where(x => x.Username == "刘备") .Where(x => x.Email == "lb@123.com") .SingleOrDefault(); Assert.IsNotNull(user); Assert.AreEqual(user.Username, "刘备");//Count int count = repository.Query<User>() .Where(x => x.Email != null || x.Email.Length <= 0) .Count(); Assert.AreEqual(count, 5); }

Repository执行过程分析

1、实体类自动生成的HBM文件

<?xml version="1.0" encoding="utf-8"?><hibernate-mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" namespace="MVCQuick.Framework.Tests" assembly="MVCQuick.Framework.Tests" xmlns="urn:nhibernate-mapping-2.2"><class name="Album" lazy="false" table="MVCQuickTest_Albums"><id name="Id" column="AlbumId" type="Int32"><generator class="identity"/></id><version name="Version"/><property name="Title"/><property name="Price"/><property name="AlbumArtUrl"/><many-to-one name="Genre" column="GenreId"/><many-to-one name="Artist" column="ArtistId"/></class><class name="Genre" lazy="false" table="MVCQuickTest_Genres"><id name="Id" column="GenreId" type="Int32"><generator class="identity"/></id><version name="Version"/><property name="Name"/><property name="Description"/><bag name="Albums" inverse="true" cascade="all"><key column="GenreId"/><one-to-many class="Album"/></bag></class><class name="Artist" lazy="false" table="MVCQuickTest_Artists"><id name="Id" column="ArtistId" type="Int32"><generator class="identity"/></id><version name="Version"/><property name="Name"/><component class="Address" name="Address"><property name="City"/><property name="Country"/><property name="State"/><property name="Street"/><property name="Zip"/></component><bag name="Albums" inverse="true" cascade="all"><key column="ArtistId"/><one-to-many class="Album"/></bag><map name="Settings" table="MVCQuickTest_ArtistSettings" lazy="false"><key column="ArtistId"/><map-key type="String"/><element type="String"/></map></class><class name="User" lazy="false" table="MVCQuickTest_Users"><id name="Id" column="UserId" type="Int32"><generator class="identity"/></id><version name="Version"/><property name="Username"/><property name="Email"/><property name="Password"/><bag name="Roles" table="MVCQuickTest_RolesUsers" lazy="false"><key column="UserId"/><many-to-many class="Role" column="RoleId"/></bag></class><class name="Role" lazy="false" table="MVCQuickTest_Roles"><id name="Id" column="RoleId" type="Int32"><generator class="identity"/></id><version name="Version"/><property name="Name"/><property name="Description"/><bag name="Users" table="MVCQuickTest_RolesUsers" lazy="false"><key column="RoleId"/><many-to-many class="User" column="UserId"/></bag></class></hibernate-mapping>

 

2、自动生成的Sql建表语句

PRAGMA foreign_keys = OFFdrop table if exists MVCQuickTest_Albumsdrop table if exists MVCQuickTest_Genresdrop table if exists MVCQuickTest_Artistsdrop table if exists MVCQuickTest_ArtistSettingsdrop table if exists MVCQuickTest_Usersdrop table if exists MVCQuickTest_RolesUsersdrop table if exists MVCQuickTest_Roles PRAGMA foreign_keys = ONcreate table MVCQuickTest_Albums ( AlbumId integer primary key autoincrement, Version INT not null, Title TEXT, Price NUMERIC, AlbumArtUrl TEXT, GenreId INT, ArtistId INT,constraint FKC10717EEF1D1C255 foreign key (GenreId) references MVCQuickTest_Genres,constraint FKC10717EEAECFE1CE foreign key (ArtistId) references MVCQuickTest_Artists )create table MVCQuickTest_Genres ( GenreId integer primary key autoincrement, Version INT not null, Name TEXT, Description TEXT )create table MVCQuickTest_Artists ( ArtistId integer primary key autoincrement, Version INT not null, Name TEXT, City TEXT, Country TEXT, State TEXT, Street TEXT, Zip TEXT )create table MVCQuickTest_ArtistSettings ( ArtistId INT not null, id TEXT, idx TEXT not null,primary key (ArtistId, idx),constraint FK62D35A09AECFE1CE foreign key (ArtistId) references MVCQuickTest_Artists )create table MVCQuickTest_Users ( UserId integer primary key autoincrement, Version INT not null, Username TEXT, Email TEXT, Password TEXT )create table MVCQuickTest_RolesUsers ( UserId INT not null, RoleId INT not null,constraint FK92B56EE2860D4243 foreign key (RoleId) references MVCQuickTest_Roles,constraint FK92B56EE27DFC8936 foreign key (UserId) references MVCQuickTest_Users )create table MVCQuickTest_Roles ( RoleId integer primary key autoincrement, Version INT not null, Name TEXT, Description TEXT )

 

3、生成的Sql查询语句

select user0_.UserId as UserId16_, user0_.Version as Version16_, user0_.Username as Username16_, user0_.Email as Email16_, user0_.Password as Password16_ from MVCQuickTest_Users user0_select user0_.UserId as UserId16_, user0_.Version as Version16_, user0_.Username as Username16_, user0_.Email as Email16_, user0_.Password as Password16_ from MVCQuickTest_Users user0_ where user0_.Username=@p0;@p0 = '刘备' [Type: String (0)]select user0_.UserId as UserId16_, user0_.Version as Version16_, user0_.Username as Username16_, user0_.Email as Email16_, user0_.Password as Password16_ from MVCQuickTest_Users user0_ order by user0_.UserId descselect user0_.UserId as UserId16_, user0_.Version as Version16_, user0_.Username as Username16_, user0_.Email as Email16_, user0_.Password as Password16_ from MVCQuickTest_Users user0_ limit @p0 offset @p1;@p0 = 3 [Type: Int32 (0)], @p1 = 3 [Type: Int32 (0)]select user0_.UserId as UserId16_, user0_.Version as Version16_, user0_.Username as Username16_, user0_.Email as Email16_, user0_.Password as Password16_ from MVCQuickTest_Users user0_ where user0_.Username=@p0;@p0 = '刘备' [Type: String (0)]select user0_.UserId as UserId16_, user0_.Version as Version16_, user0_.Username as Username16_, user0_.Email as Email16_, user0_.Password as Password16_ from MVCQuickTest_Users user0_ where user0_.Username=@p0;@p0 = '诸葛亮' [Type: String (0)]select user0_.UserId as UserId16_, user0_.Version as Version16_, user0_.Username as Username16_, user0_.Email as Email16_, user0_.Password as Password16_ from MVCQuickTest_Users user0_ where user0_.Username=@p0 and user0_.Email=@p1;@p0 = '刘备' [Type: String (0)], @p1 = 'lb@123.com' [Type: String (0)]select cast(count(*) as INT) as col_0_0_ from MVCQuickTest_Users user0_ where user0_.Email is not null or length(user0_.Email)<=@p0;@p0 = 0 [Type: Int32 (0)]

 

一切尽在掌握!

 

Repository(ORuM)的实现过程感兴趣,可以看看前面的博文,在此不再详述。 

源代码下载:http://mvcquick.codeplex.com/   

转载于:https://www.cnblogs.com/guyoung/archive/2011/10/23/2221787.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)