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
{
private long _id;
private string _name;
private IList<BlogItem> _items;
public virtual long Id
{
get { return _id; }
set { _id = value; }
}
public virtual IList<BlogItem> Items
{
get { return _items; }
set { _items = value; }
}
public virtual string Name
{
get { return _name; }
set { _name = value; }
}
}
}using System;
namespace Eg
{
public class BlogItem
{
private long _id;
private DateTime _dateTime;
private string _text;
private string _title;
private Blog _blog;
public virtual Blog Blog
{
get { return _blog; }
set { _blog = value; }
}
public virtual DateTime DateTime
{
get { return _dateTime; }
set { _dateTime = value; }
}
public virtual long Id
{
get { return _id; }
set { _id = value; }
}
public virtual string Text
{
get { return _text; }
set { _text = value; }
}
public virtual string Title
{
get { return _title; }
set { _title = value; }
}
}
}The XML mappings should now be quite straightforward.
<?xml version="1.0"?>
<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"?>
<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.Tool.hbm2ddl;
namespace Eg
{
public class BlogMain
{
private ISessionFactory _sessions;
public void Configure()
{
_sessions = new Configuration()
.AddClass(typeof(Blog))
.AddClass(typeof(BlogItem))
.BuildSessionFactory();
}
public void ExportTables()
{
Configuration cfg = new Configuration()
.AddClass(typeof(Blog))
.AddClass(typeof(BlogItem));
new SchemaExport(cfg).create(true, true);
}
public Blog CreateBlog(string name)
{
Blog blog = new Blog();
blog.Name = name;
blog.Items = new List<BlogItem>();
using (ISession session = _sessions.OpenSession())
using (ITransaction tx = session.BeginTransaction())
{
session.Save(blog);
tx.Commit();
}
return blog;
}
public BlogItem CreateBlogItem(Blog blog, string title, string text)
{
BlogItem item = new BlogItem();
item.Title = title;
item.Text = text;
item.Blog = blog;
item.DateTime = DateTime.Now;
blog.Items.Add(item);
using (ISession session = _sessions.OpenSession())
using (ITransaction tx = session.BeginTransaction())
{
session.Update(blog);
tx.Commit();
}
return item;
}
public BlogItem CreateBlogItem(long blogId, string title, string text)
{
BlogItem item = new BlogItem();
item.Title = title;
item.Text = text;
item.DateTime = DateTime.Now;
using (ISession session = _sessions.OpenSession())
using (ITransaction tx = session.BeginTransaction())
{
Blog 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 (ISession session = _sessions.OpenSession())
using (ITransaction tx = session.BeginTransaction())
{
session.Update(item);
tx.Commit();
}
}
public void UpdateBlogItem(long itemId, string text)
{
using (ISession session = _sessions.OpenSession())
using (ITransaction tx = session.BeginTransaction())
{
BlogItem item = session.Load<BlogItem>(itemId);
item.Text = text;
tx.Commit();
}
}
public IList<BlogItem> ListAllBlogNamesAndItemCounts(int max)
{
IList<BlogItem> result = null;
using (ISession session = _sessions.OpenSession())
using (ITransaction tx = session.BeginTransaction())
{
IQuery 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<BlogItem>();
tx.Commit();
}
return result;
}
public Blog GetBlogAndAllItems(long blogId)
{
Blog blog = null;
using (ISession session = _sessions.OpenSession())
using (ITransaction tx = session.BeginTransaction())
{
IQuery q = session.createQuery(
"from Blog as blog " +
"left outer join fetch blog.Items " +
"where blog.id = :blogId"
);
q.SetParameter("blogId", blogId);
blog = (Blog) q.List()[0];
tx.Commit();
}
return blog;
}
public IList<Blog> ListBlogsAndRecentItems()
{
IList<Blog> result = null;
using (ISession session = _sessions.OpenSession())
using (ITransaction tx = session.BeginTransaction())
{
IQuery q = session.CreateQuery(
"from Blog as blog " +
"inner join blog.Items as blogItem " +
"where blogItem.DateTime > :minDate"
);
DateTime date = DateTime.Now.AddMonths(-1);
q.SetDateTime("minDate", date);
result = q.List<Blog>();
tx.Commit();
}
return result;
}
}
}