ORM with the PassionITe difference!

PassionORM® is an Enterprise level .Net ORM solution free for non-commercial use. We made it free because we want everyone to be able to use PassionORM and help set a standard of focused development on business logic rather than wasting the effort on focusing on the plumbing (data-access code).

Linking business applications correctly with their Data is no longer a tedious task. With PassionORM® the conceptual model closely reflects the business requirements while abstracting the error prone data-accessing code writing.

Because we hire passionate people, we put passion in our products.


Features

Full Type Safety

  • In a fully type safe ORM, there is no reference to any table or field name that needs to be written in a magic constant (string between quotes).
  • The problem with a non-type safe ORM is that when a table name changes, your code just compiles as if nothing is wrong. Then when you run this code later the program will fail unexpectedly as it tries to access this table.
  • With PassionORM if you change for instance a table name, the code will generate a compilation error. The problem can then be addressed before testing and debugging has even started.






Multi-database Support

PassionORM allows you to connect to multiple data sources in one application

  • Connect to an virtually unlimmeted amount of datasources.
  • Microsoft SQL Server, My SQL (experimental) and Oracle (experimental).



Extremely little code "overhead"

Overhead code is any code related to something else than the logic you’re paid to develop. No customer wants you to write a lot of code that does not directly relate to the solution of the problem.

PassionORM removes as much as possible overhead code. Here is an incomplete list of the overhead code that PassionORM handles for you:

  • SQL / Stored procedure invocation.
  • Dataset / DataReader handling.
  • Connection and Connection String handling.
  • The majority of transaction handling.
  • Multithreading considerations.
  • Database concurrency and locking.
 

Code with classical ADO.NET Implementation

    SqlConnection sqlcon = new SqlConnection("Data Source=THOTH;Initial Catalog=TaskList; Integrated Security=SSPI;");
    sqlcon.Open();
    SqlCommand sqlCmd = new SqlCommand("SELECT t.ID, t.ParentTaskID, ts.Name, r.Name, " +
                            "t.Description, t.WorkedHours, t.TargetDate, t.EntryDate, " +
                            "t.PriorityID, CAST(t.VersionStamp AS BIGINT) AS VersionStamp " +
                            "FROM Task t " +
                            "INNER JOIN TaskStatus ts ON ts.ID = StateID " +
                            "INNER JOIN Resource r ON r.ID = AssignedToID " +
                            "WHERE ts.Name = @ThisState AND r.Name = @ThisResource", sqlcon);

    SqlParameter param1 = new SqlParameter("@ThisState", SqlDbType.NVarChar);
    param1.Value = "Open";

    SqlParameter param2 = new SqlParameter("@ThisResource", SqlDbType.NVarChar);
    param2.Value = "Project Management";

    sqlCmd.Parameters.Add(param1);
    sqlCmd.Parameters.Add(param2);

    SqlDataAdapter adapter = new SqlDataAdapter(sqlCmd);
    DataTable TaskTable = new DataTable("TaskListing");
    adapter.Fill(TaskTable);
    
 

Code with PassionORM

     TaskStatus ts = TaskStatusEnum.Open;
     Resource r = Resource.TryLoad("Project Management");
     TaskCollection tasks = r.TasksEx(Task.Members.State ==  ts);
    



Runtime and compiletime code generation

The bigger the solution, the more likely you are to have bugs in your code.

PassionORM creates on the fly, while the program is running, some of the code that usually is where most of the errors are concentrated.

PassionORM has the following code generation facilities:

  • Runtime generation of SQL commands.
  • Runtime generation of Mapping code to transfer data from a resultset/datareader into your custom object.
  • Compiletime generation and maintenance of the Data Access Layer (DAL).



Complex Query Support

Inner join’s, 'not in' constructions, 'union' and complex 'where' clauses are supported by PassionORM and written in an intuitive manner.

Retrieving record-set or collection

    // Sample WHERE clause
    TaskCollection criticalTasks = Task.AllEx(Task.Members.Priority == 
                  (TaskPriority)TaskPriorityEnum.Critical);
    
    // Sample NOT IN
    TaskCollection unassignedTasks = Task.All.ExcludeTaskAssignment;
    
    // Sample UNION
    TaskCollection unionOfTasks = criticalTasks + unassignedTasks;
    



Highly optimized to spawn little queries

PassionORM reduces the amount of queries the ORM spawns to the database in a unique way.

Since the amount of queries directly impacts the performance, this might be the most important feature of all.

The queries in most cases are fired only when needed. This means that costly “ back and forth trips “ are minimized.

 

Sample PassionORM auto-generated SQL command

        SELECT [T1].[ID], 
        [T1].[Name], 
        [T1].[TeamLeadID], 
        CAST([T1].[VersionStamp] AS BIGINT) AS [VersionStamp] 
        FROM [Team] T1, 
        [PersonInTeam] T2, 
        [Person] T3, 
        [Resource] T4, 
        [Task] T5, 
        [TaskPriority] T6 
        WHERE (([T2].[TeamID] = [T1].[ID]) 
        AND (([T3].[ID] = [T2].[PersonID]) 
        AND (([T4].[ID] = [T3].[ID]) 
        AND (([T5].[AssignedToID] = [T4].[ID]) 
        AND ((([T5].[StateID] = 4) 
        AND ([T5].[PriorityID] = 1)) 
        AND ([T6].[ID] = [T5].[PriorityID])))))) 
        GROUP BY [T1].[ID], 
        [T1].[Name], 
        [T1].[TeamLeadID], 
        CAST([T1].[VersionStamp] AS BIGINT)
      

The statements generated above prevent common pitfalls developers often have. These include the use of '[]' for tables/columns that are using reserved keywords, proper '()' for clauses, casting data to the appropriate data type expected by a data client, proper syntax logic that gets what is really asked and much more.




Object graph awareness

PassionORM reads database tables relationships.

PassionORM synchronizes Foreign Key fields with Primary Key fields automatically.

Object graph awareness  

Sample PassionORM code

                        // Load company from DB
                        Company t = Company.TryLoad(Company.Members.Name == "PassionITe");
                        
                        // Create some departments
                        Department d1 = t.AddDepartment();
                        d1.Name = "Development";

                        Department d2 = t.AddDepartment();
                        d2.Name = "Support";
                        
                        // Saves the company with all its newly created departments
                        t.Save();                       
                        



Custom written logic and events support

You can write custom code on top of the ORM generated type safe classes.

Custom written logic is not lost when the classes are re-generated after changes are made to the database model.

PassionORM exposes events for all the most common actions (create/load/save/delete).

Example of usage:

a developer decides to add a new initial task for every newly added Person.

With this event system, developers no longer need to remind their teams to always create a new Task if they create a new Person or write triggers or stored procedures in the database, but they can simply hook up the task creation code to the "AddEvent" event of the "Person" object.

  • One significant advantage is that developers will never accidentally forget to create this task, even if there are new additions to the development team that were never informed about it.
 

Sample code for subscribing to PassionORM events

        [fwEventHandler()]
        partial class Person
        {
            [fwEvent(fwEventTypes.AddEvent, typeof(Person))]
            static void Person_AddEvent(Person sender, fwEventArgs args)
            {
                //Person add event handling code goes here
            }
            [fwEvent(fwEventTypes.ChangeEvent, typeof(Person))]
            static void Person_ChangeEvent(Person sender, fwEventArgs args)
            {
                //Person change event handling code goes here
            }
            [fwEvent(fwEventTypes.LoadEvent,typeof(Person))]
            static void Person_LoadEvent(Person sender, fwEventArgs args)
            {
                //Person load event handling code goes here
            }
        }
    



 
Compare


Resources