例如,我有两个类: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);
这是一个好方法吗? 如果不是,我应该使用什么方法来访问数据?
由于
答案 0 :(得分:8)
您正在做的事情基本上是Active Record模式的实现。很多人使用它,这是一种非常有效的方法。如果您的申请非常复杂,或者您对关注点分离感到迷恋,您可能会发现以下内容有帮助:
我建议使用DDD(domain-driven design)方法。 DDD使用所谓的存储库模式。 DDD将您的应用程序及其关注点分为不同的层,“模型/域”,“基础架构”和“服务”。
存储库是属于基础结构层的模式。 Customer
或Employer
(或Monster
和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派生的新类。这使您可以快速采用数据库基础结构中的更改。例如,您可以创建一个从XML文件读取数据的FooRepository,或者使用NHibernate从Postgres数据库读取数据的文件。
您还可以阅读关于DDD的this,this和this 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个)?最终哪一个最快,最适合您的项目?