Micro ORMs, alternatives to Entity Framework ? Part 2
Introduction of some Micro ORMs: Simple.Data
Scenario Used
In order to show reusable examples, I’m using AdventureWork Database (2014), you can download it here.
I will use the WorkOrder table and the Product table, I will use also a business project named Orders that is a projection on there two tables.
Some Micro ORMs are able to manage relationships between tables and populate objects linked by a navigation property, some not, so we will use the projection instead of entities introduced before.
Simple.Data
- It’s syntax is fully dynamic syntax, consequence: no IntelliSense
- Compatible with multiple databases: SQL Server, Oracle, Mysql, SqlLite, PostgreSql, SqlAnyWhere, Informix Microsoft Access
- Uncomplicated syntax (LINQ-like)
- Supports transactions
- Mandatory to create an AdHoc query to populate an object (relationships are not supported)
- Weird database connection management : « Simple.Data is quite aggressive in closing connections and holds no open connections to a data store by default, so you can keep the Database object returned from the Open*() methods hanging around without worrying.»
- Not testable unitarily
- Doesn’t provide Async queries
- Not compatible with .NET Core
- Was promising but unfortunately it is no longer updated since 2013
Code samples :
Required entities and business objects for our scenario :
public class Orders { public Orders() { } public int Id { get; set; } public string ProductName { get; set; } public int? Quantity { get; set; } public DateTime? Date { get; set; } } //Db entity public class WorkOrder { public WorkOrder() { } public int WorkOrderId { get; set; } public int ProductID { get; set; } public int? OrderQty { get; set; } public int? StockedQty { get; set; } public int? ScrappedQty { get; set; } public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } public DateTime? DueDate { get; set; } public int? ScrapReasonID { get; set; } public DateTime? ModifiedDate { get; set; } }
Repository sample :
public class MassiveRepository public class SimpleDataRepository { private dynamic _dbConnection; private dynamic _workerId; private dynamic _productName; private dynamic _orderQty; private dynamic _dueDate; public SimpleDataRepository() { _dbConnection = Database.OpenNamedConnection("AdventureWorks2014"); _workerId = _dbConnection.WorkOrder.WorkOrderID; _productName = _dbConnection.WorkOrder.Product.Name; _orderQty = _dbConnection.WorkOrder.OrderQty; _dueDate = _dbConnection.WorkOrder.DueDate; } public List GetOrders() { List data = _dbConnection.WorkOrder.Select(_workerId, _productName, _orderQty, _dueDate).Skip(0).Take(500); return data.Select(x => new Orders { Id = x.WorkOrderID, ProductName = x.Name, Quantity = x.OrderQty, Date = x.DueDate }).ToList(); } public Orders GetOrderById(int id) { dynamic data = _dbConnection.WorkOrder.Select(_workerId, _productName, _orderQty, _dueDate).Find(_workerId == id); return new Orders { Id = data.WorkOrderID, ProductName = data.Name, Quantity = data.OrderQty, Date = data.DueDate }; } public void Add(WorkOrder workOrder) { _dbConnection.WorkOrder.Insert(workOrder); //dynamic data = _dbConnection.WorkOrder.Insert(ProductId : 1, OrderQty : 10, StockedQty : 50 .......); } public void Update(WorkOrder workOrder) { _dbConnection.WorkOrder.UpdateByWorkOrderId(workOrder); //_dbConnection.WorkOrder.Update(WorkOrderId: workOrder.WorkOrderId); } public void Delete(WorkOrder workOrder) { _dbConnection.WorkOrder.DeleteByWorkOrderId(workOrder.WorkOrderId); //_dbConnection.WorkOrder.Delete(WorkOrderId: workOrder.WorkOrderId); } }
Like it’s name Simple.Data is very simple !