[英]Active Record Design Pattern?
我最近一直在研究各种ORM框架(主要是.net),并且看到Active Record设计模式通常用于保存数据。
我只是想知道每个人对活跃记录模式的看法是什么? 我个人认为它对数据对象承担了太多责任,无论是数据容器还是实体bean。 我总是从一个中央控制器接近持久化对象,这个对象暴露了一个方法,比如Persist(),它接受一个接口说IEntityBean,而不是让bean对它的持久性进行排序。 这也是我为人口所采用的方法我得到一个数据集并且通常填充bean而不是让bean接收数据集并填充自己。 我只是不喜欢有逻辑的豆子。 这是一种老式的做法还是让别人分享我的恐惧?
ORM框架如何不使用活动记录模式映射表来对象和对象表? 是一个中央控制器来控制持久的坏方法吗?
感谢您的意见!
我没有使用ActiveRecord,因为ActiveRecord违反了SRP大的时间 。 我们有自己的内部定制ORM。
在我们的ORM中,我们充分利用了C#3.0功能。 我们有一个名为Application.Infrastructure
的库项目,它承载业务对象的所有基类。 我们有一个验证框架和使用属性的自动映射。
ORM大量使用Attributes来自动完成大多数繁琐的任务,如映射和验证。 我可以在框架中添加新功能作为新方面。
TableMapping
属性将告诉我们此对象映射到哪个表。 DataFieldMapping
属性将告诉我们该对象的属性映射到哪个coloumn。 validation framework
允许我在指定的ValidationAttribute
的帮助下验证每个字段。
每个业务对象都有一个基类EntityBase,而业务集合具有EntityCollectionBase。 我们使用传统的数据集进行数据库交互,我们为EntityBase,EntityCollectionBase,DataRow和DataTable编写了扩展方法。 此exntesion方法将从对象的属性中读取映射元数据,并通过Reflection执行[双向]映射。
在我的应用程序中,示例业务对象将如下所示。
User.cs
[TableMapping("Users")]
public class User : EntityBase
{
#region Constructor(s)
public AppUser()
{
BookCollection = new BookCollection();
}
#endregion
#region Properties
#region Default Properties - Direct Field Mapping using DataFieldMappingAttribute
private System.Int32 _UserId;
private System.String _FirstName;
private System.String _LastName;
private System.String _UserName;
private System.Boolean _IsActive;
[DataFieldMapping("UserID")]
[DataObjectFieldAttribute(true, true, false)]
[NotNullOrEmpty(Message = "UserID From Users Table Is Required.")]
public override int Id
{
get
{
return _UserId;
}
set
{
_UserId = value;
}
}
[DataFieldMapping("UserName")]
[Searchable]
[NotNullOrEmpty(Message = "Username Is Required.")]
public string UserName
{
get
{
return _UserName;
}
set
{
_UserName = value;
}
}
[DataFieldMapping("FirstName")]
[Searchable]
public string FirstName
{
get
{
return _FirstName;
}
set
{
_FirstName = value;
}
}
[DataFieldMapping("LastName")]
[Searchable]
public string LastName
{
get
{
return _LastName;
}
set
{
_LastName = value;
}
}
[DataFieldMapping("IsActive")]
public bool IsActive
{
get
{
return _IsActive;
}
set
{
_IsActive = value;
}
}
#region One-To-Many Mappings
public BookCollection Books { get; set; }
#endregion
#region Derived Properties
public string FullName { get { return this.FirstName + " " + this.LastName; } }
#endregion
#endregion
public override bool Validate()
{
bool baseValid = base.Validate();
bool localValid = Books.Validate();
return baseValid && localValid;
}
}
BookCollection.cs
/// <summary>
/// The BookCollection class is designed to work with lists of instances of Book.
/// </summary>
public class BookCollection : EntityCollectionBase<Book>
{
/// <summary>
/// Initializes a new instance of the BookCollection class.
/// </summary>
public BookCollection()
{
}
/// <summary>
/// Initializes a new instance of the BookCollection class.
/// </summary>
public BookCollection (IList<Book> initialList)
: base(initialList)
{
}
}
在使用NHibernate本身进行了大量实验之后,我使用了Castle ActiveRecord (基于NHibernate)。 只要您不读取或写入大量对象,ORM方法就足够快。
使用NHibernate,您必须通过XML文件指定映射(使其与代码保持同步的痛苦),并且上次使用它时,可以使用代码中的Attributes来定义它们。 显然,这在代码反射和代码生成的背景下大量使用以执行所有“魔术”。 通过使用ActiveRecord进一步发展,我对ORM方法的可维护性感到满意。
我在Castle ActiveRecord中不喜欢的是你必须从基础ActiveRecordBase派生你的ActiveRecord类。 什么有时是一个强烈的要求,因为基本上你可能想从其他东西派生它,让它只行为像ActiveRecord。 有一种方法可以通过使用ActiveRecordMediator来避免这种情况。
我没有使用MS解决方案的经验,因为当时我需要一个他们什么都没有的东西(他们用一个工作框架来得太晚了)。 Castle Project提供了几乎所有我需要的更大的Web开发,从反转控制容器到高级ORM。
DataMapper更强大。
我喜欢的唯一ORM(虽然我不知道.Net)和我认为足够灵活的是SQLAlchemy,看看一些例子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.