我最近一直在研究各种ORM框架(主要是.net),并且看到Active Record设计模式通常用于保存数据。
我只是想知道每个人对活跃记录模式的看法是什么?我个人认为它对数据对象承担了太多责任,无论是数据容器还是实体bean。我总是从一个中央控制器接近持久化对象,这个对象暴露了一个方法,比如Persist(),它接受一个接口说IEntityBean,而不是让bean对它的持久性进行排序。这也是我为人口所采用的方法我得到一个数据集并且通常填充bean而不是让bean接收数据集并填充自己。我只是不喜欢有逻辑的豆子。这是一种老式的做法还是让别人分享我的恐惧?
ORM框架如何不使用活动记录模式映射表来对象和对象表?是一个控制持续不良方法的中央控制器吗?
提前感谢您的意见!
答案 0 :(得分:4)
我不使用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)
{
}
}
答案 1 :(得分:1)
在使用NHibernate本身进行了大量实验后,我使用了Castle ActiveRecord(基于NHibernate)。只要您没有阅读或编写大量对象,ORM方法的执行速度就足够快。
使用NHibernate,您必须通过XML文件指定映射(使其与代码保持同步非常痛苦),并且上次使用它时,可以使用代码中的Attributes来定义它们。显然,这会在代码反射和代码生成的背景下大量使用来执行所有“魔法”。通过使用ActiveRecord,我对ORM方法的可维护性感到满意。
我在Castle ActiveRecord中不喜欢的是你必须从基础ActiveRecordBase派生你的ActiveRecord类。什么有时是一个强烈的要求,因为基本上你可能想从其他东西派生它,让它只行为像ActiveRecord。有一种方法可以使用ActiveRecordMediator来避免这种情况。
我还没有使用MS解决方案的经验,因为在我需要一个他们什么都没有的时候(他们在工作框架上来得太晚了)。 Castle Project几乎提供了从控制容器反转到高级ORM的更大Web开发所需的一切。
答案 2 :(得分:0)
DataMapper更强大。
我喜欢的唯一ORM(虽然我不知道.Net)而且我认为足够灵活的是SQLAlchemy,请看一些例子。