2014年1月3日星期五

NHibernate初学者指南(9):会话管理(附实例)

进行.NET开发,你可能已经接触到下面的一种或几种类型的应用程序:
1. 基于Web的应用程序,包括Silverlight。 
2. WinForm或WPF应用程序 
3. Windows服务。

当然,还有很多其他类型的应用程序,但是它们使用NHibernate会话管理的方法和上面三种类型的程序相同。
本篇文章,我们创建一个简单的Silverlight应用程序实现基本的会话管理。Silverlight是基于Web的应用程序,所以这里用到的技术也同样适用于其他类型的web程序(ASP.NET MVC或WebForms)。
1. 在SSMS中新建一个数据库:SilverlightSample。
2. 打开VS,创建一个Silverlight的项目:SilverlightSample,如下图:
 创建Silverlight项目
3. 当询问是否将Silverlight程序寄宿在网站时,保持默认设置即可,单击OK继续。
寄宿在网站中
4. 在SilverlightSample.Web项目中,添加对NHibernate,NHibernate.ByteCode.Castle和Fluent NHibernate三个程序集的引用。
5. 在SilverlightSample.Web项目中添加一个Product.cs类文件,在里面定义一个简单的Product实体,如下面的代码所示:
public class Product
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}
6. 在SilverlightSample.Web项目中添加一个ProductMap.cs类文件,定义Product实体的映射,如下面的代码所示:
public class ProductMap : ClassMap<Product>
{
    public ProductMap()
    {
        Id(x => x.Id).GeneratedBy.HiLo("1000");
        Map(x => x.Name);
    }
}
7. 在SilverlightSample.Web项目中添加一个SessionProvider类。这个类有一个SessionProvider类型的静态属性:Instance。如下面的代码所示:
public class SessionProvider
{
    public static SessionProvider Instance { get; set; }
}
8. 在这个类中添加一个ISessionFactory类型的静态实例变量,如下面的代码所示:
private static ISessionFactory sessionFactory;
9. 在类中添加一个静态的构造函数,初始化Instance属性,如下所示:
static SessionProvider()
{
    var provider = new SessionProvider();
    provider.Initialize();
    Instance = provider;
}
10. 在类中添加一个空private构造函数,不初始化,如下所示:
private SessionProvider()
{
}
11. 在类中添加一个Initialize方法,它包含配置NHibernate,创建数据库架构和创建session工厂的代码:
private void Initialize()
{
    const string connString =
            "server=.;database=SilverlightSample;" +
            "user id=sa;password=sasa;";
    var configuration = Fluently.Configure()
                        .Database(MsSqlConfiguration.MsSql2008
                        .ConnectionString(connString)
                        .ShowSql())
                        .Mappings(m => m.FluentMappings
                        .AddFromAssemblyOf<Product>())
                        .BuildConfiguration();
    var exporter = new SchemaExport(configuration);
    exporter.Execute(true, true, false);
    sessionFactory = configuration.BuildSessionFactory();
}
12. 再添加一个OpenSession方法,它返回ISession。
public ISession OpenSession()
{
    return sessionFactory.OpenSession();
}
13. 添加一个Silverlight-enabled WCF Service到SilverlightSample项目,名字为:ProductService,如下图:
创建ProductService
14. 删除类中默认的方法,添加一个CreateProduct方法,代码如下所示:
public class ProductService
{
    [OperationContract]
    public int CreateProduct()
    {
        using (var session = SessionProvider.Instance.OpenSession())
        using (var transaction = session.BeginTransaction())
        {
            var product = new Product { Name = "Apple" };
            var productId = (int)session.Save(product);
            transaction.Commit();
            return productId;
        }
    }
}
15. 编译解决方案,这一步对下一步很重要!
16. 在Solution Explorer窗口中,右击SilverlightSample项目,选择Add Service Reference..
17. 在Add Service Reference对话框中,单击"Discover"按钮。Visual Studio会在本地发现ProductService.svc这个服务。
添加服务
18. 单击OK继续。Visual Studio会创建web service的一个代理,可以被客户端使用,如下图:
19. 在SilverlightSample项目中的MainPage.xaml中添加一个按钮,代码如下:
    <Grid x:Name="LayoutRoot" Background="White">
        <Button x:Name="CreateProduct" Content="Create Product"
Click="OnCreateProduct" Width="100" Height="30"/>
    </Grid>
20. 为前面代码的单击事件处理程序添加代码,使用ProductService代理在数据库中创建一个product。如下面的代码所示:
private void OnCreateProduct(object sender, RoutedEventArgs e)
{
    var client = new ProductService.ProductServiceClient();
    client.CreateProductCompleted += OnProductCreated;
    client.CreateProductAsync();
}
private void OnProductCreated(object sender, CreateProductCompletedEventArgs e)
{
    MessageBox.Show(string.Format(
    "Created product with id={0}", e.Result));
}
运行程序,单击CreateProduct按钮,程序弹出一个对话框,说明插入成功,如下图:
运行结果
到此,一个简单的程序就完成了。