因此,与大多数新的.NET开发人员一样,您开始在任何地方传递DataSet,尽管工作做得不对,但这似乎并不正确。
下一个进展通常是创建扩展DAL基类的实体对象,以便你拥有ie
public class User : UserDAL
{
//User specific methods
}
public class UserDAL
{
//Bunch of user specific properties
public User Load(int Id)
{
//Some low level ADO calls
}
private User LoadFromDataSet(DataSet ds)
{
//Load entity properties from DataSet
}
}
用户使用ADO.NET扩展具有低级别数据访问调用的UserDAL对象。
从这里开始,您将了解到这种实现意味着您与数据访问层绑定,并且您可以使用单独的实体,数据访问对象和DAO接口进行模拟,或者在需要时轻松交换DAO。即。
public UserDAO : IUserDAO
{
//Data access Functions
}
使用泛型和反射或良好的ORM,您可以减轻一些更常见的数据访问CRUD操作,即
Public UserDAO<User> : BaseDAO<User>, IUserDAO
{
//BaseDAO deals with basic crud so more custom data access methods can go here
}
基本上这就是我目前所处的位置,除了使用IoC来解决我想要的特定IUserDAO之外的其他一些好的做法。但是当我看到这个结构的优势时,我也感觉我错过了旧的User.Load(1)方法调用。
我想知道将IUserDAO注入用户实体并将其用于基本的CRUD操作会是一件坏事吗?
我的理解是,作为POCO,用户实体不会通过网络传递任何问题,并且添加诸如Save(),Load()等方法在数据传输对象意义上将没有相关性。
但是,据说说我的实体通常有延迟加载的集合,这在DTO意义上没有任何意义。此外,使用WFP,我相信可以选择和选择我想要序列化的属性,或者至少我可以创建一个新的UserDTO,当我需要通过网络发送它。
基本上,除了那个问题,使我的用户实体包含DataAccess相关方法的其他问题是什么?也有人可以澄清我所说的是否被称为活跃的记录模式还是其他的东西?
编辑:
cristianlibardo指出:至于潜在的缺点,存在与存活代码的更大耦合,在关注/更新关联,可测试性和查询时的反应。
会有更大程度的耦合,但我想的是像下面那样:
public class User
{
IUserDAO userDAO;
public User()
{
userDAO = IoCContainer.Resolve<IUserDAO>;
}
public User(IUserDAO userDAO)
{
this.userDAO = userDAO;
}
//DAL methods
}
所以耦合应该是最小的,至于可测试性,我不认为它是一个问题因为我可以将模拟DAO注入到实体中。
感谢Brian Hasden,这些都是非常好的资源,但我想我只是想为我显然要做的事情辩护。谢谢你说的理由。
答案 0 :(得分:1)
BTW,我通常将脏标志与实体结合起来,以了解属性何时被更改,以便在实体未更改时不进行不必要的保存调用。
通常情况下,实际上并没有为私人成员包含getter和setter的实体意味着您正在使用贫血域模型。这是一种相当有争议的反模式。
您可以在以下网址找到有关它的更多信息:
http://www.martinfowler.com/bliki/AnemicDomainModel.html http://wrschneider.blogspot.com/2005/01/avoiding-anemic-domain-models-with.html http://www.dotnetjunkies.com/WebLog/richardslade/archive/2007/03/07/209401.aspx
答案 1 :(得分:1)
是的,你所描述的内容听起来就像是活动记录(数据库行被创建成一个具有从数据库持久存储到数据库的逻辑的对象)。毫无疑问,这是一种有效的技术。
至于潜在的缺点,存在与存活代码的更大耦合,在关注/更新关联,可测试性和查询时的反应。
答案 2 :(得分:0)
保持域类继承模型的持久性主要是为了编写可理解和可维护的代码。
坚持是你班级真正职责的正交关注点。我注意到,从DAO继承方法任意地将世界划分为两类,从责任和行为的角度来看,这两类都没有区别。课程的哪一方往往会随着时间而改变。您不希望该更改影响该类的API以及与其他类的交互。
示例:今天说,您的Product类使用通过IoC检索的IPriceCalculator。明天,您决定需要修改每个产品的算法,因此您的IPriceCalculator将成为数据驱动的。这可能是一个痛苦的变化,特别是如果您的价格计算器已经有一个提供重要功能的基类。
此示例突出了另一个考虑因素:从DAO类继承意味着您的User类失去了继承可能具有有用行为的Person类的能力。 (在.NET世界中,MarshalByRefObject是人们需要继承的公共基类,它可能与基于继承的DAO要求相冲突。)对于单继承,为了获得可能是单独关注的功能而继承并不理想。 / p>