1

例如,我有两个类: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);
}

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

Foo foo = Foo.Get(id);

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

Foo.Update(newfoo);

Foo.Delete(newfoo);

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

谢谢

4

3 回答 3

8

您所做的基本上是Active Record模式的实现。许多人使用它,这是一种完全有效的方法。但是,如果您的应用程序非常复杂,或者如果您对关注点分离有迷恋,您可能会发现以下内容很有帮助:

我推荐一种 DDD(领域驱动设计)方法。DDD 使用所谓的存储库模式。DDD 将您的应用程序及其关注点分成不同的层,“模型/域”、“基础设施”和“服务”。

存储库是属于基础设施层内部的一种模式。Customer像or Employer(或Monsterand )这样的业务对象Weapon位于模型层内部,代表您的“域”(您尝试建模)的核心,它们还负责业务逻辑。服务层可用于简化、编排跨多个模型的活动。

对于每个域模型(例如,您的类 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 派生的新类。这使您可以快速适应数据库基础架构中的更改。例如,您可以创建一个 FooRepository,它从 XML 文件中读取数据,或者使用 NHibernate 从 Postgres db 中读取数据。

你也可以阅读这篇这篇这篇关于 DDD 的文章。

于 2009-08-18T07:10:55.757 回答
1

它始终取决于您正在编写的软件类型。

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

在我正在开发的一个相当大的企业软件中,我们将所有 NH 访问权限放在一个单独的程序集中。HQL 和其他特定的东西不属于业务逻辑。这也使得单元测试变得容易。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);
于 2009-08-18T07:10:39.580 回答
0

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

如果它是一小组类,比如少于 5 个,并且永远不会成为一个巨大的企业应用程序,那么您可以查看这个NHibernate 查询助手(shameless plug)或 Codesmith 生成其NHibernate 类的方式。

通过第一个链接,您只需让您的对象保存数据,对业务规则执行任何验证:例如,有一个名为IsValidEmail(). 然后,您使用查询管理器执行创建、读取更新删除任务,例如

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 种(或 3 种,如果您包含存储库模式)中,您更愿意使用哪一种?最终哪一个是最快和最适合您的项目的?

于 2009-08-18T09:00:38.810 回答