database - 事件记录设计模式?

标签 database design-patterns orm oop

我最近一直在研究各种 ORM 框架(主要是 .net),发现 Active Record 设计模式通常用于持久化数据。

我只是想知道大家对事件记录模式的看法是什么?我个人认为它把太多的责任放在了数据对象上,无论它只是一个数据容器还是一个实体 bean。我总是从一个中央 Controller 处理持久化对象,该 Controller 公开一个方法,例如 Persist(),它接受一个接口(interface),比如 IEntityBean,而不是让 bean 将其持久化。这也是我为人口采取的方法我得到一个数据集并一般地填充 bean,而不是让 bean 接受数据集并填充它自己。我只是不喜欢有逻辑的 bean 。这是一种过时的方法还是其他人和我一样担心?

不使用事件记录模式的 ORM 框架如何映射表到对象以及对象到表?控制持久化的中央 Controller 是一种错误的方法吗?

提前感谢您的意见!

最佳答案

我不使用 ActiveRecord,因为 ActiveRecord 经常违反 SRP。我们有自己的内部定制 ORM。

编辑

在我们的 ORM 中,我们大量利用了 C# 3.0 的特性。我们有一个名为 Application.Infrastructure 的库项目,它托管我们业务对象的所有基类。我们有一个验证框架和使用属性的自动映射。

ORM 大量使用属性来自动执行大多数繁琐的任务,例如映射和验证。我可以在框架中添加新功能作为新方面。

TableMapping 属性会让我们知道这个对象映射到哪个表。 DataFieldMapping 属性会让我们知道对象对象的属性映射到哪个列。 验证框架 允许我在指定的 ValidationAttribute 的帮助下验证每个字段。

每个业务对象都有一个基类 EntityBase,业务集合有 EntityCollectionBase。我们使用传统的数据集进行数据库交互,我们为 EntityBase、EntityCollectionBase、DataRow 和 DataTable 编写了扩展方法。这种扩展方法将从对象的属性中读取映射元数据,并通过反射执行[双向]映射。

示例业务对象在我的应用程序中看起来像这样。

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)
    {
    }
}

关于database - 事件记录设计模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3174129/

相关文章:

database - 将 Twitter Streaming API 推文原样转储到 Apache Cassandra 进行后期处理

java - 为一名观察者提供多个主题的正确设计模式

hibernate - 如何在 Intellij IDEA 的 Hibernate 中使用逆向工程进行 ORM?

java - 为具有不同参数的方法设计接口(interface)

php - 处理 100K 条目数据馈送的更有效方法?

python - 如何在 Django orm 中链接和过滤 3 个表中的数据

mysql - 对于 MySQL 的使用和性能,哪个是多个小查询或一个大查询更好?

android - 在Room Persistence Library中使任何列自动生成(不是主键)

MySQL:使用 IF 条件对重复 ID 进行分组

java - 事件队列条目的设计模式请求