Я не использую ActiveRecord, потому что ActiveRecord постоянно нарушает SRP . у нас есть собственный внутренний ORM.
EDIT
В нашем ORM мы активно используем возможности C # 3.0. У нас есть проект библиотеки под названием Application.Infrastructure
, в котором размещены все базовые классы для наших бизнес-объектов. У нас есть структура проверки и автоматическое сопоставление с использованием атрибутов.
ORM интенсивно использует атрибуты для автоматизации большинства утомительных задач, таких как сопоставление и проверка. Я могу добавить новую функцию в качестве нового аспекта в рамках.
Атрибут TableMapping
позволит нам узнать, к какой таблице относится этот объект. Атрибут DataFieldMapping
позволит нам узнать, к какому столбцу относится свойство объекта theject. 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)
{
}
}