在NHibernate中制作数据访问方法的最佳方法是什么?

时间:2009-08-18 06:23:56

标签: c# nhibernate data-access-layer static-methods

例如,我有两个类:Foo和Bar。这些类映射到一些表。

至于现在,我为每个类都有静态方法:添加,更新,删除,获取。

E.g.: 

public class Foo
{
   private Guid _id;
   private string _someProperty;

   static Foo Get(Guid id);
   static void Add(Foo foo);
   static void Update(Foo foo);
   static void Delete(Foo foo);
}

所以,当我需要用我的对象做smth时我会这样说:

Foo foo = Foo.Get(id);

Foo newfoo = new Foo();
Foo.Add(newfoo);

Foo.Update(newfoo);

Foo.Delete(newfoo);

这是一个好方法吗? 如果不是,我应该使用什么方法来访问数据?

由于

3 个答案:

答案 0 :(得分:8)

您正在做的事情基本上是Active Record模式的实现。很多人使用它,这是一种非常有效的方法。如果您的申请非常复杂,或者您对关注点分离感到迷恋,您可能会发现以下内容有帮助:

我建议使用DDD(domain-driven design)方法。 DDD使用所谓的存储库模式。 DDD将您的应用程序及其关注点分为不同的层,“模型/域”,“基础架构”和“服务”。

存储库是属于基础结构层的模式。 CustomerEmployer(或MonsterWeapon)等业务对象位于模型层内,代表“域”的核心(您尝试建模),他们还负责业务逻辑。服务层可用于简化,协调跨多个模型的活动。

对于每个域模型(例如,您的类Foo和Bar),您有一个处理数据库访问的存储库。这样,您就可以进行数据库调用并将模型分开。

public interface IFooRepository
{
     Foo Get(Guid guid);
}

public class FooRepository : IFooRepository
{
     public Foo Get(Guid guid)
     {
         //... DB voodoo magic happening
         return foo;
     }
}

如果您厌倦了始终为您的存储库编写锅炉代码,也可以创建通用IRepository<T>

您还应该研究依赖注入/控制反转,因为这种方法非常适用于它。

这种方法的好处是,您可以轻松实现从IFooRepository派生的新类。这使您可以快速采用数据库基础结构中的更改。例如,您可以创建一个从XML文件读取数据的FooRepository,或者使用NHibernate从Postgres数据库读取数据的文件。

您还可以阅读关于DDD的thisthisthis article

答案 1 :(得分:1)

它总是取决于您所编写的软件类型。

就个人而言,我不喜欢实体本身是否进行任何数据访问。该实体负责管理其字段和属性,不应该做更多。

在我正在开发的一个非常大的企业软件中,我们将所有NH访问权限放在一个单独的程序集中。 HQL和其他特定的东西不属于业务逻辑。这使得单元测试也很容易。有a similar architecture explained on CodeProject,值得一读。

我喜欢有一些允许插入,删除和更新任何实体的通用方法,因为使用NH很容易,而且你不必一遍又一遍地编写相同的代码。例如:

void Store(object entity);
void Delete(object entity);
T Get<T>(object id);
IList<T> GetAll<T>();
void Lock(object entity);

特定接口中的其他特定方法,例如:

IList<Product> GetProductsWithAttribute(string attributeName, string attributeValue);

答案 2 :(得分:0)

如果你正在编写大型应用程序,那么Kitsune所说的是最好的方法。

如果它是一小组类,比如少于5个,并且永远不会成为一个巨大的企业应用程序,你可以看看这个NHibernate query helper (shameless plug)或者Codesmith生成它NHibernate classes的方式。< / p>

使用第一个链接,您只需让对象保存数据,对业务规则执行任何验证:例如,使用名为IsValidEmail()的方法。然后,您使用查询管理器执行 C reate, R ead, U pdate, D elete任务,例如:

NHibernateManager<User> manager = new NHibernateManager<User>();
User name = manager.ReadFirst();

// All items filtered (using OR)
IList<User> list = manager.OrList("@Name", "12345", "@Name", "54321");

// Paged
list = manager.Page(1,10);

CodeSmith模板比这更先进,但是工作原理类似。他们向您展示了NHibernate会议。

你所做的ActiveRecord模式也非常好,只会被域驱动的纯粹主义者嘲笑。唯一的问题是诸如User,Contact之类的对象负责NHibernate查询和会话,但相反,该对象很好地自包含。

您更喜欢在2中使用哪一个(如果包含Repository模式,则为3个)?最终哪一个最快,最适合您的项目?