The persistent classes represent a weblog, and an item posted in a weblog. They are to be modelled as a standard parent/child relationship, but we will use an ordered bag, instead of a set.
using System;
using System.Collections.Generic;
namespace Eg
{
public class Blog
{
public virtual long Id { get; set;}
public virtual IList<BlogItem> Items { get; set;}
public virtual string Name { get; set;}
}
}using System;
namespace Eg
{
public class BlogItem
{
public virtual Blog Blog { get; set;}
public virtual DateTime DateTime { get; set;}
public virtual long Id { get; set;}
public virtual string Text { get; set;}
public virtual string Title { get; set;}
}
}The XML mappings should now be quite straightforward.
<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Eg" namespace="Eg">
<class
name="Blog"
table="BLOGS"
lazy="true">
<id
name="Id"
column="BLOG_ID">
<generator class="native"/>
</id>
<property
name="Name"
column="NAME"
not-null="true"
unique="true"/>
<bag
name="Items"
inverse="true"
lazy="true"
order-by="DATE_TIME"
cascade="all">
<key column="BLOG_ID"/>
<one-to-many class="BlogItem"/>
</bag>
</class>
</hibernate-mapping><?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="Eg" namespace="Eg">
<class
name="BlogItem"
table="BLOG_ITEMS"
dynamic-update="true">
<id
name="Id"
column="BLOG_ITEM_ID">
<generator class="native"/>
</id>
<property
name="Title"
column="TITLE"
not-null="true"/>
<property
name="Text"
column="TEXT"
not-null="true"/>
<property
name="DateTime"
column="DATE_TIME"
not-null="true"/>
<many-to-one
name="Blog"
column="BLOG_ID"
not-null="true"/>
</class>
</hibernate-mapping>The following class demonstrates some of the kinds of things we can do with these classes, using NHibernate.
using System;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
namespace Eg
{
public class BlogMain
{
private ISessionFactory _sessions;
public void Configure()
{
_sessions = new Configuration().Configure()
.BuildSessionFactory();
}
public void ExportTables()
{
var cfg = new Configuration().Configure();
new SchemaExport(cfg).Create(true, true);
}
public Blog CreateBlog(string name)
{
var blog = new Blog
{
Name = name,
Items = new List<BlogItem>()
};
using (var session = _sessions.OpenSession())
using (var tx = session.BeginTransaction())
{
session.Save(blog);
tx.Commit();
}
return blog;
}
public BlogItem CreateBlogItem(Blog blog, string title, string text)
{
var item = new BlogItem
{
Title = title,
Text = text,
Blog = blog,
DateTime = DateTime.Now
};
blog.Items.Add(item);
using (var session = _sessions.OpenSession())
using (var tx = session.BeginTransaction())
{
session.Update(blog);
tx.Commit();
}
return item;
}
public BlogItem CreateBlogItem(long blogId, string title, string text)
{
var item = new BlogItem
{
Title = title,
Text = text,
DateTime = DateTime.Now
};
using (var session = _sessions.OpenSession())
using (var tx = session.BeginTransaction())
{
var blog = session.Load<Blog>(blogId);
item.Blog = blog;
blog.Items.Add(item);
tx.Commit();
}
return item;
}
public void UpdateBlogItem(BlogItem item, string text)
{
item.Text = text;
using (var session = _sessions.OpenSession())
using (var tx = session.BeginTransaction())
{
session.Update(item);
tx.Commit();
}
}
public void UpdateBlogItem(long itemId, string text)
{
using (var session = _sessions.OpenSession())
using (var tx = session.BeginTransaction())
{
var item = session.Load<BlogItem>(itemId);
item.Text = text;
tx.Commit();
}
}
public IList<object[]> ListAllBlogNamesAndItemCounts(int max)
{
IList<object[]> result;
using (var session = _sessions.OpenSession())
using (var tx = session.BeginTransaction())
{
var q = session.CreateQuery(
"select blog.id, blog.Name, count(blogItem) " +
"from Blog as blog " +
"left outer join blog.Items as blogItem " +
"group by blog.Name, blog.id " +
"order by max(blogItem.DateTime)"
);
q.SetMaxResults(max);
result = q.List<object[]>();
tx.Commit();
}
return result;
}
public Blog GetBlogAndAllItems(long blogId)
{
Blog blog = null;
using (var session = _sessions.OpenSession())
using (var tx = session.BeginTransaction())
{
var q = session.CreateQuery(
"from Blog as blog " +
"left outer join fetch blog.Items " +
"where blog.id = :blogId"
);
q.SetParameter("blogId", blogId);
blog = q.UniqueResult<Blog>();
tx.Commit();
}
return blog;
}
public IList<object[]> ListBlogsAndRecentItems()
{
IList<object[]> result = null;
using (var session = _sessions.OpenSession())
using (var tx = session.BeginTransaction())
{
var q = session.CreateQuery(
"from Blog as blog " +
"inner join blog.Items as blogItem " +
"where blogItem.DateTime > :minDate"
);
var date = DateTime.Now.AddMonths(-1);
q.SetDateTime("minDate", date);
result = q.List<object[]>();
tx.Commit();
}
return result;
}
}
}It requires some configuration settings in web.config, such as:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- Add this element -->
<configSections>
<section
name="hibernate-configuration"
type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>
<!-- Add this element -->
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
<property name="connection.connection_string">
Server=localhost\SQLEXPRESS;initial catalog=Eg;Integrated Security=True
</property>
<mapping assembly="Eg" />
</session-factory>
</hibernate-configuration>
<!-- Leave the other sections unchanged -->
<system.web>
...
</system.web>
</configuration>