From msdn magazine article (a bit old but valid) : http://msdn.microsoft.com/en-us/magazine/ff898427.aspx

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
, , , ,

After getting frustrated with the fact that Entity Framework and NHibernate does not resolve my needs, I am writing my own ORM tool to finalize one very important part of enterprise architecture.

Here are the features that are included (hope to finish by tomorrow)

  1. Mutliple entity classes (one per each)
  2. Single Data Provider Class
    1. One Interface IDataProvider
    2. One Class which inherits I[Model]DataProvider (SQL[Model]DataProvider)
      1. [Model] to be renamed by the model name provided
    3. One mocked class using moq framework (http://code.google.com/p/moq/)
  3. SQL[Model]DataProvider will also implement retry logic in case of certain cases such as
    1. Deadlock
    2. Connection Timeout etc.
    3. In a nutshell the following error codes : -1,-2,2,53,1222,1205
  4. Will obviously generate related stored procedures and utilize them :)
  5. Entities will be able to track simultaneous changes and will be able to throw exception if data changed before update!
  6. Entities will implement [DataContract] & [DataMember] so that usage in WCF will be a lot easy
  7. As you may see from here generated codes will implement Abstract Factory (Provider) design pattern and possibility of Singleton is also there.
I think all of those will give me the best ORM that I would need.
I’ve named it as SevDer ORM+ and first version will be completed by tomorrow
  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
, , , , , , , , , , , ,

After doing enough research on both, what we’ve end up doing is; not using any ORM tool.

ORMs are designed to do rapid development for RIA (Rich Internet Applications) where performance is not a big concern.
Yes, ORM can speed up your development such as EF 4.0 or NH but they all lack one very important thing which is support for Stored Procedures for general select which shall be by default. All ORMs are focused on eliminating that and trying to optimize queries without SP.

If you ask me, SP are most useful when you use for select in general because you can really optimize the execution plan and it will be cached on SQL server. So in all subsequent calls to the database with same routine, SQL server will always know the execution plan and it will save time. [SP's execution plans are cached on SQL server.]

Therefore not using ORM is my choice.

Here are what I lose by not using ORM

  1. oData
  2. Extra quick development
  3. Default behavior of throwing exception on an update where data was already changed before the update (concurrency handling)
What I gain by not using ORM
  1. Will get the best performance
  2. My code will not have unnecessary extra code which I may not even use
  3. Will use SP’s the way they are supposed to be used
  4. Will abstract data layer in the most perfect manner
  5. Improve existing code generator to do my own ORM (no oData)
    1. All entities will be generated with DataContracts, DataMembers (necessary in WCF)
    2. Proper implementation of RETRY logic in SQL Exceptions (if you ever want to move into SQL Azure, you need to do this also)
    3. Will implement concurrency handling
As a result, I have tons of gains by not using .
Most important is achieving best performance and SP usage on selects.
I hope I’ve helped.
Please let me know if any more digging in this is required.
  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
, , , , , , , , , , , ,

We are comparing to select the next robust data layer and almost in the end

Here are the requirements

  1. Needs to be available as a service
    1. Very important to segment out security to limited resources [PCI]
    2. Very helpful when testing [helps in mocking also]
  2. Needs to be easy to adopt
    1. If possible build in minutes
  3. Needs to be flexible in migrations/versions
  4. Needs to work with existing stored procedures
  5. Shall force developers write better code
Given those here are the comparisons and the choice
NHibernate the good
  1. Most mature and longest in market
  2. Easy caching
  3. Versions are not big issue, backwards compatible
  4. Lazy loader per entity
NHibernate the not good
  1. You need to still write a lot of code
  2. No designer/GUI
  3. Service is not provided out of the box
  4. Longer learning curve
Entity Framework the good
  1. Easy to build with GUI support [in minutes]
  2. Easy to convert to service in minutes also
  3. Easy Lazy loader for the whole model
  4. Migrations/versions are manageable and will support earlier version clients with few tricks
  5. Works with existing procedures
  6. Links entities without any effort
  7. Code First, Model First, Database First Support
  8. Data Changed notification [Don't know if NHibernate has this]
Entity Framework the not good
  1. Not yet mature enough
  2. Caching is not provided out of the box
  3. Select procedures are not that easy like Delete, Update & Insert
  4. Default behavior may make developers yield to, not to use stored procs hence poorer performance may occur & worst of all deadlocks can occur [not so different in NHibernate also]
So at this moment EF 4.0 + WCF DataServices is my choice to move forward, starting tomorrow.
Ohh friends, please correct me in the areas where I am not correct.
  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
, , , , , , ,

I’ve always been big fan of using stored procedures due to the fact that you have a lot more control over your database and query plans to be cached but surprised for certain facts that EF can come very close to the level you want and in certain cases can perform much better [with data caching options of course].

Still huge fan of using stored procs to keep my DBA happy.

Want to know what others also think!

Checkout this for more details
Get Microsoft Silverlight

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
, , , , , , ,

A very simple implementation with 2 different databases (distributed transactions):

http://www.luisrocha.net/2011/08/managing-transactions-with-entity.html

using (TransactionScope scope = new TransactionScope())
{
    // Save changes but maintain context1 current state.
    context1.SaveChanges(SaveOptions.DetectChangesBeforeSave);

    // Save changes but maintain context2 current state.
    context2.SaveChanges(SaveOptions.DetectChangesBeforeSave);

    // Commit succeeded since we got here, then completes the transaction.
    scope.Complete();

    // Now it is safe to update context state.
    context1.AcceptAllChanges();
    context2.AcceptAllChanges();
}

 

A bit more complex looking but another effective way

http://social.msdn.microsoft.com/Forums/en/adodotnetdataservices/thread/e66651c0-9202-4049-a8f4-55971b8b359d

 

public class WcfDataService1 : DataService<WebApplication2.AdHocContainer7StorageEntities>, IDisposable
    {
        private TransactionScope transaction;
        private bool disposed;
        private bool error;

        public WcfDataService1()
        {
            this.ProcessingPipeline.ProcessingChangeset += new EventHandler<EventArgs>(ProcessingPipeline_ProcessingChangeset);
            this.ProcessingPipeline.ProcessedChangeset += new EventHandler<EventArgs>(ProcessingPipeline_ProcessedChangeset);
        }

        ~WcfDataService1()
        {
            Dispose(false);
        }

        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
            config.UseVerboseErrors = true;
        }

        private void ProcessingPipeline_ProcessingChangeset(object sender, EventArgs args) 
        {
            transaction = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 30));
        }

        private void ProcessingPipeline_ProcessedChangeset(object sender, EventArgs args) 
        {
            if (!error)
            {
                transaction.Complete();
            }
            this.Dispose(); // will rollback the transaction if it has not been commited
        }

        protected override void  HandleException(HandleExceptionArgs args)
        {
            error = true;
 	        base.HandleException(args);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if(!disposed)
            {
                if(disposing)
                {
                    if (transaction != null)
                    {
                        transaction.Dispose();
                    }
                }

                disposed = true;
            }
        }
    }

 

 

 

 

 

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
, , , , , , ,