Modify for Entity Framework

Jan 18, 2013 at 6:36 PM

Thank you for a great project.

Can this be ported to keep data in SQL Azure by using Entity Framework.

this.ReadingEntity += new EventHandler<ReadingWritingEntityEventArgs>(DataServiceContextEx_ReadingEntity);
this.WritingEntity += new EventHandler<ReadingWritingEntityEventArgs>(DataServiceContextEx_WritingEntity);

How would you hook into EM to encrypt / decrypt data, like you do with TableServiceContext?

Thanks
Jun 9, 2014 at 4:04 PM
In your class deriving from your EF context class, you can
  • override the method SaveChanges to encrypt users being created or modified within the context
  • create a event handler for ObjectContext.ObjectMaterialized which will decrypt users
The following example shows how to encrypt a user object in your SQL database with EntityFramework code first
public class Context : Entities
{
       private AzureTableCrypto _cryptoService;

        public Context()
            : base()
        {
            // Casting object for EF database first
            ((IObjectContextAdapter) this).ObjectContext.ObjectMaterialized += ObjectContextOnObjectMaterialized;
        }

        public override int SaveChanges()
        {

            var changeSet = ChangeTracker.Entries<User>().Where(entity => entity.State.HasFlag(System.Data.Entity.EntityState.Modified) || entity.State.HasFlag(System.Data.Entity.EntityState.Added));
            if (changeSet.Any())
            {
                foreach (DbEntityEntry<User> entry in changeSet)
                {
                    Encrypt(entry.Entity);
                }
            }

            return base.SaveChanges();
        }

        private void ObjectContextOnObjectMaterialized(object sender, ObjectMaterializedEventArgs objectMaterializedEventArgs)
        {
            if (objectMaterializedEventArgs.Entity.GetType().BaseType.Name == "User")
            {
                var user = (User)objectMaterializedEventArgs.Entity;
                Decrypt(user);
            }
        }

        // Lazy loading of the crypto service
        private void InitializeCryptoService()
        {
            if (_cryptoService == null)
            {
                var storageAccount = Microsoft.WindowsAzure.CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);
                _cryptoService = new AzureTableCrypto(EncryptionStrengthEnum.VeryWeak, storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
                var section = (NameValueCollection)WebConfigurationManager.GetSection("certificate");
                _cryptoService.LoadCertificateByThumbprint(section["thumbprint"]);
            }
        }

        private void Decrypt(User user)
        {
            InitializeCryptoService();
            // Code to encrypt you object
        }

        private void Encrypt(User user)
        {
           InitializeCryptoService();
           // Code to decrypt your object
        }
}