{"id":293,"date":"2009-09-08T09:00:08","date_gmt":"2009-09-08T13:00:08","guid":{"rendered":"http:\/\/blogs.law.harvard.edu\/brandonhaynes\/?p=293"},"modified":"2009-09-08T10:13:17","modified_gmt":"2009-09-08T14:13:17","slug":"entity-framework-model-adapter","status":"publish","type":"post","link":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/2009\/09\/08\/entity-framework-model-adapter\/","title":{"rendered":"Released: Entity Framework Runtime Model Adapter"},"content":{"rendered":"<div>\n<p>The\u00a0<a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.data.objects.objectcontext.aspx\">ObjectContext<\/a> is a base class for all <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa697427(VS.80).aspx\">Entity Framework<\/a> models. \u00a0While there exists a rich API for interacting with a model, the ability to adapt the underlying schema to the (potentially varying) run-time environment presents a serious shortcoming for many production applications. \u00a0These variances can potentially involve myriad considerations, from a change in database owner to modified table names (often by a production-specific prefix). \u00a0This can have a serious impact on\u00a0large-scale deployment of applications using the Entity Framework (those familiar with my DotNetNuke-related work will immediately understand this consideration, where a run-time environment may be configured to use an arbitrary database owner or table prefix).<\/p>\n<p>To remedy this issue, I have developed an <a href=\"http:\/\/efmodeladapter.codeplex.com\/\">adaptive framework<\/a> that converts an Entity Framework model generated by the Visual Studio designer into a highly configurable result. \u00a0This framework is designed to be flexible, extendable, and highly customizable.<\/p>\n<p><!--more--><\/p>\n<p>My goals for any satisfactory solution were as follows:<\/p>\n<ul>\n<li>Run-time adjustment of an Entity Framework EDMX model, including:\n<ul>\n<li>Connection-based adaptation (e.g. use of a runtime-specified connection string)<\/li>\n<\/ul>\n<\/li>\n<li>Run-time adjustment of model schema, including:\n<ul>\n<li>Adjusting data-level table prefixes or suffixes<\/li>\n<li>Adjusting the owner of database objects<\/li>\n<\/ul>\n<\/li>\n<li>Continued use of the Visual Studio Model designer<\/li>\n<li>No tedious changes in the compiler-generated code<\/li>\n<li>Continued use of an assembly-embedded EDMX model (and thereby no additional or external schema deployment files)<\/li>\n<\/ul>\n<p>It is unfortunate that the object model exposed by the Entity Framework is so frustratingly difficult to extend.\u00a0 The underlying metadata are overwhelmingly read-only (and, frustratingly, many potentially useful classes are either internal or sealed).\u00a0 Indeed, it seemed that there was no simple remedy to the problem at hand.<\/p>\n<p>My solution utilizes the following approach:<\/p>\n<ul>\n<li>A Connection adapter is used to walk a model (and optionally adapt a connection string based upon a run-time environment) [Goal 1].<\/li>\n<li>During the model walk, a dependency-injected model adapter is utilized to adapt various attributes of the model (currently storage, mapping, and association) [Goal 2]. \u00a0Walking is reasonably inexpensive, and since the models are cached by type, performance is not affected.<\/li>\n<li>The framework requires only a change in base class to an AdaptingObjectContext (which itself derives from an ObjectContext). \u00a0This allows the Visual Studio editor to continue to be utilized, and no direct EDMX manipulation is required (though, frustratingly, the base class of an entity model is not adjustable through the Visual Studio UI, necessitating a change in the code-generated file) [Goal 3, 4, 5].<\/li>\n<\/ul>\n<p>I use dependency injection to adapt attributed entities (database, table, and function names) into their adapted counterparts. \u00a0Additional adapters could easily be constructed for other domains, should any arise (to illustrate this point, a NonTransformingAdapter is included in the release, which performs no transformations).<\/p>\n<p><a href=\"http:\/\/efmodeladapter.codeplex.com\/\">Click here<\/a> to access the project site for additional\u00a0<a href=\"http:\/\/efmodeladapter.codeplex.com\/\">details<\/a> and\u00a0<a href=\"http:\/\/efmodeladapter.codeplex.com\/Release\/ProjectReleases.aspx\">downloads<\/a>.<\/p>\n<p>As is all of my DotNetNuke-related work, this framework is available under a liberal open-source license for ready public consumption (and extension). \u00a0Though the content herein is protected under the license below, be sure to consult the project license (New BSD) for integration-related details.<\/p>\n<p>As always, feedback is appreciated.<\/p>\n<p>B<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>The\u00a0ObjectContext is a base class for all Entity Framework models. \u00a0While there exists a rich API for interacting with a model, the ability to adapt the underlying schema to the (potentially varying) run-time environment presents a serious shortcoming for many production applications. \u00a0These variances can potentially involve myriad considerations, from a change in database owner [&hellip;]<\/p>\n","protected":false},"author":1933,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3901,142],"tags":[13219,4944,3900,19472],"class_list":["post-293","post","type-post","status-publish","format-standard","hentry","category-entity-framework-ef","category-technology","tag-adaptation","tag-data","tag-entity-framework","tag-entity-framework-ef"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/posts\/293","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/users\/1933"}],"replies":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/comments?post=293"}],"version-history":[{"count":6,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/posts\/293\/revisions"}],"predecessor-version":[{"id":317,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/posts\/293\/revisions\/317"}],"wp:attachment":[{"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/media?parent=293"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/categories?post=293"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/brandonhaynes\/wp-json\/wp\/v2\/tags?post=293"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}