Micro ORMs, alternatives to Entity Framework ? Part 9

 

<< Previous article (Part 8)

What conclusion(s) can we make ?

Let’s summarize first principals features we described for each Micro ORM before in a user friendly table here:

Legends :

 Disappointing

 Good

 Excellent

 Yes

 No

 Yes, but not verified

Note that they :

  • All support the execution of stored procedures, views, functions
  • Are all protected from SQL injection (queries parameterization)

What we liked ?

  • NPoco for simplicity of its syntax and performance
  • Dapper for its outstanding performance and its amazing community
  • OrmLite for its double LINQ-like and SQL syntax, and for its rich functionalities and performance

Finally….

Even if we love some Micro ORMs and they are more performant than Entity Framework, they don’t provide all Entity Framework’s functionalities, and they don’t support unit tests as Entity Framework does (by mocking its DbContext).

In fact it depends on what you are looking for 🙂

I hope this suite of articles helped you to make a choice 😉

If you need to check the source code, you can find it here : https://github.com/AnthonyGiretti/MicroOrmDemo.net

Micro ORMs, alternatives to Entity Framework ? Part 8

 

<< Previous article (Part 7)

Performance comparisons

I did some benchmarks, only with Select query.

First benchmark scenario

I used single query that bring back from database 500 rows, here the query:

 SELECT TOP 500 [WorkOrderID] AS Id, P.Name AS ProductName, [OrderQty] AS Quantity, [DueDate] AS Date
 FROM [AdventureWorks2014].[Production].[WorkOrder] AS WO 
 INNER JOIN[Production].[Product] AS P ON P.ProductID = WO.ProductID

Second benchmark scenario

I used a serie of 500 queries that returns 1 row:

SELECT [WorkOrderID] AS Id, P.Name AS ProductName, [OrderQty] AS Quantity, [DueDate] AS Date
FROM [AdventureWorks2014].[Production].[WorkOrder] AS WO 
INNER JOIN[Production].[Product] AS P ON P.ProductID = WO.ProductID
WHERE WorkOrderID = @Id

Let’s see what happened….

 

Most of time Micro Orms are faster than Entity Framework, but less than ADO.NET

 

What conclusions can we make ?

Micro ORMs, alternatives to Entity Framework ? Part 3

 

<< Previous article (Part 2)

Introduction of some Micro ORMs: Massive

Scenario Used

You can find the scenario used in a last article here.

Massive

  • Provide only dynamic data
  • Compatible with few relational databases: SQL Server, Oracle, SqlLite, PostgreSql
  • Dual SQL Syntax and LINQ / SQL Hybrid
  • Provides basic commands only, simplistic syntax (no join for example)
  • Interesting performances
  • Provide Async queries
  • Supports transactions
  • Mandatory to create an AdHoc query to populate an object (relationships are not supported)
  • Mandatory to inherit its Pocos from a class called DynamicModel (Map its data into another similar typed object or be satisfied with dynamic data)
  • Not compatible with .NET Core
  • No NuGet package, download two files on the GitHub repo
  • Not testable unitarily

Code samples :

Required entities and business objects for our scenario :

public class OrdersDynamic : DynamicModel
    {
        public OrdersDynamic() : base("AdventureWorks2014", "Production.WorkOrder", "WorkOrderID") { }

        public int Id { get; set; }
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public DateTime Date { get; set; }
    }

    public class WorkOrderDynamic : DynamicModel
    {
        public WorkOrderDynamic() : base("AdventureWorks2014", "Production.WorkOrder", "WorkOrderID") { }

        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; }
    }

    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; }
    }

    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; }
    }

Repository sample :

public class MassiveRepository
    {
        public List GetOrders()
        {
            var table = new OrdersDynamic();

            return table.Query(@"SELECT TOP 500 [WorkOrderID] AS Id, P.Name AS ProductName, [OrderQty] AS Quantity, [DueDate] AS Date
                                 FROM [AdventureWorks2014].[Production].[WorkOrder] AS WO 
                                 INNER JOIN[Production].[Product] AS P ON P.ProductID = WO.ProductID").Select(x => new Orders {
                                                                                                                                Id = x.Id,
                                                                                                                                ProductName = x.ProductName,
                                                                                                                                Quantity = x.Quantity,
                                                                                                                                Date = x.Date
                                                                                                                            }).ToList();
        }

        public Orders GetOrderById(int id)
        {
            var table = new OrdersDynamic();

            var data =  table.Query(@"SELECT  [WorkOrderID] AS Id, P.Name AS ProductName, [OrderQty] AS Quantity, [DueDate] AS Date
                                     FROM [AdventureWorks2014].[Production].[WorkOrder] AS WO 
                                     INNER JOIN[Production].[Product] AS P ON P.ProductID = WO.ProductID
                                     WHERE WorkOrderID = @0", id).FirstOrDefault();

            return new Orders
            {
                Id = data.Id,
                ProductName = data.ProductName,
                Quantity = data.Quantity,
                Date = data.Date
            };
        }

        public void Add(WorkOrder workOrder)
        {
            var table = new WorkOrderDynamic();
            table.Insert(workOrder);
        }

        public void Update(WorkOrder workOrder)
        {
            var table = new WorkOrderDynamic();
            table.Update(workOrder, "WHERE WorkOrderID = @0", workOrder.WorkOrderId.ToString());
        }
        public void Delete(WorkOrder workOrder)
        {
            var table = new WorkOrderDynamic();
            table.Delete("WHERE WorkOrderID = @0",  workOrder.WorkOrderId.ToString());
        }
    }

Pretty but heavy to use with its DynamicModel isn’t it? 🙂

 

Now let’s talk about PetaPoco.