ADO.NET Entity Framework & Your Data Access Layer


Published on

This presentation highlights three ways in which to use the ADO.NET Enterprise Framework in conjunction with your DAL: 1) EF == DAL, 2) Encapsulation of EF, and 3) Partial Encapsulation of EF.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • “How many of you think that the Entity Framework will be the last data access technology from Microsoft?”What I hope to do in this session is give you some things to think about when you go home next week or the week after and you begin to examine how you will utilize the Entity Framework in your architecture.Frankly, we’re talking about software that, while it has been in beta for some time, is still in beta. This isn’t to say the Entity Framework is not ready for production, but rather that we don’t have as a community of architects a lot of experience with this technology. So the best practices are going to formulate over the next 6 to 24 months. What we do have however, is our experience and ability to use that experience to reason over this new technology. So in short, don’t forget the things you already know.
  • An o/rm is an object relational mapper – it handles the persistence, qureying, management of transaction and conccurrency for you.Often people are scared of ORMs, and what I try to point out is that using an ORM is not like handing the keys of your house to a stranger. All it is is a simple, more advanced and automated tool.There are three main elements:An API for CRUD operationsA query model plus an ad hoc query language to speed up the definition of most querieisAn API for mapping metadata (like classes to tables)
  • An o/rm is an object relational mapper – it handles the persistence, qureying, management of transaction and conccurrency for you.Often people are scared of ORMs, and what I try to point out is that using an ORM is not like handing the keys of your house to a stranger. All it is is a simple, more advanced and automated tool.There are three main elements:An API for CRUD operationsA query model plus an ad hoc query language to speed up the definition of most querieisAn API for mapping metadata (like classes to tables)
  • This is the entity framework. It’s a good slide for a conceptual overview. The EF is built on top of the classic ADO.NET providers – SQL Client, Oracle, etc. On top of that is the entity data provider. The entity data provider looks just like the ADO.NET data providers – the ADO.NET data providers has SQL Connection, SQL Command, ExecuteReader – so does the EntityClient Data Provider. It doesn’t have, however, the tradititional update capabilities – there’s no executenonquery or data adapters. But, the projection of data is very similar, and there’s actually a SQL language in here called entity SQL – so if you have some code that works with data readers today, and you just have your SQL in a string, you can do the same thing with your entityclient data provider.On the left you have these XML files – this metadata. And there are three files – the store schema, which is an XML document that describes the data in your database. The reason that the entity framework exists is this thing right here – the conceptual schema. The idea of the conceptual schema is that it is of a different normalization than your database. The entityclient data provider talks at this layer – the conceptual schema.Between the store schema and the conceptual schema is the map. Now, you may be asking yourself why this is any different than Linq to SQL. The difference is that this is a very rich mapping, your conceptual and store schemas can be significantly different. You can only accomplish fragments of this in linq to SQL. The other difference is L2S means SQL Server – the EF is agnostic of the underlying database.Most people like to think of the entity framework up at this level, the object services. This is where you perform LINQ. There are services that are exposed at this level.
  • For architects and developers focused on the underlying architecture, the ultimate question is – where does this code go? Where should we write this code? Should it be at our data access layer? Do we need a DAL? Should we just write this code in our business logic?
  • Why do we even have a DAL, or any kind of layer? SoC.Specifically, we want our components to have as small a responsibility as possible. We want them highly cohesive, so they only have a few or at best one reason to change. And we also want our components in the layers to be loosely coupled, so that we can pull out a component and put in a different one. These are some of the basic tenets of structured design that have been around since the 70’s.
  • So, what if there was no DAL? What if the EF is our DAL?Well, there are going to be conceptual objects called EF entities. The question is, are these our business objects? Or are they my data transfer objects? Or is this just some kind of plumbing in my business layer? What are these things?If you use the EF as your DAL, you are taking these entities and putting them out into your application. Now, this can be a very productive thing, but it can also be a little bit scary.So, if we wrote these queries directly in my business layer, would I have the separation of concerns that I care about? High cohesion and loose coupling. What my schema be independent – yes it would. Would my plumbing and infraustructure to talk to SQL or Oracle or DB2 be loosely coupled – yes it would. Would my business objects be separated from my data access technology – not necessarily.
  • So, this is what the architecture looks like. And while it’s just one of many possible architectures, I think this makes a lot of sense in many situations. We have a presentation layer – forms and views of the data – a business layer – with business objects – and at the bottom an infrastructure layer for data access.Here we have the conceptual schema, our mapping to the store schema. We have the client provider – which is the thing that actually talks to the entity framework. We have object services – which is useful for change tracking and identity management and object materialization – and then we have the actual entities themselves.All this stuff starts off in the DAL. What happens when we write this code in the business layer? When we write this kind of query, what do we need in this layer? Well, we need the entities. We also have the object context.What happens if we want to do data binding now with this object – there’s a great databinding story with entity framework entities. So, now we bring our entities into the user interface layer.What this means is that all our layers need to have a reference to the, which is the library. This isn’t a bad library – it’s part of the .net runtime – but you’d need to reference this in all your layers.If this doesn’t bother you, then I think this is a great architecture.
  • Identity and change tracking: which really means that we have really good update support. We can just change properties on our save methods, and everything is persisted back into the database, across the whole conceptual map – it’s quite powerful.Conceptual data model – There are two key interfaces when we talk about LINQ: Ienumerable and Iqueryable. When you have a LINQ query over something that’s enumerable, like a collection, all it’s doing under the covers is a foreach loop for you. That’s a lot different from the entity framework and L2S – these implement something called Iqueryable. So, when you write a complex query, it doesn’t execute and bring back objects right away – it’s understanding the full query, in memory, in a lamda expression tree, and you can compose that query and manipulate that query until the final query is actually needed and needs to be executed, and then the query is sent down in its full form to the database. This is a great way to allow a database to do what it does best, rather than having us iterate over objects.Downsides. All about tradeoffs.-In the past, the tooling really didn’t support an object first approach, or a model driven approach. It really was a database first approach. This has changed in .NET 4.0.In the past, entities are not pure plain old CLR objects. They had a base class, a bunch of attributes in them, there’s code generated – yes, you can extend them with partial classes, but it didn’t quite feel like a pure environment.Because your talking objectcontexts, etc., you’re really talking to the entity framework rather than generic interfaces. This makes it hard to switch out to something else, even L2S.You can work around this, but the data validation support is a bit limited.
  • So, here’s some code for data validation. The top half is the declaration for a phone property in the partial class generaged by the entity framework. The getter is obvious. In the setter, it calls a typed method. It looks a little like an event, but it’s not an event. It’s called a partial method, which is a method that’s not implemented yet. So what happens is if this method is not implemented somewhere else in the partial class, the compiler takes it out at compile time. Then it goes and does some other stuff.So, to validate the phone number, is you create your own partial class in a separate file outside of the designer so that the generator doesn’t blow your code away, and you implement the onphonechanging method. In here, you can interegate the value, and respond accordingly.However, if you look at the flow of the code, you can’t stop the data from getting into the field. So, if someone says phone equals ABC you can’t stop it – you can only respond to it. Sure you can throw an exception, but that’s a reactive response, not proactive. So, you might have to create some kind of customer error handler, but it’s not exceptional.
  • So, why?SoC – I don’t want my business layer to know something about the entity framework. If you don’t’ care about this, then don’t worry – just go down the previous architecture we discussed.Testable components. If you want to be able to test your business objects without having to drill into the database, if you want automated unit testing, etc., you may want to encapsulate this.If you want additional logic down in your data access components. For example, you may have a method called GetProducts, but depending on the day of the week you don’t want to return all the objects. Some of these rules can be put down in the conceptual model, but others may require some additional logic to be embedded.If you are really concerned about performance and logic, you may want to prevent people that write against your business layer from generating queries that hit your database – they may not be as efficient at writing these statement.So, you might want to have more control over the objectcontext lifetime. If you don’t mind your business developers leaving objects around you really won’t know how much memory your application is consuming.SQL generation – I may want to have control over this generation, and influence it. If I just expose objectqueries and let people do linqquerieis over the entity framework it becomes very difficult for a DBA to know how to optimize the database for the kind of queries.Other thing is eager loading baked into the DAL. What is this? L2S has lazy loading – when you query a customers collection, and you decide you want customer orders, it will go out and run a query right away – Nhibernate and L2S support this. EF takes a different approach in that the philosophy doesn’t believe that referencing a property should result in a query – you need to be more intentional. You use eager loading to say that you want to load order information with customers. This way, you have only one query that is executed.
  • So, I’d suggest there are three approaches. Full, partial, and a hybrid.Full – in this environment, we don’t use the entity framework entity classes, or the objectcontext class, anywhere outside of our DAL. So that means the EF entities are not our business objects. We create our own custom business objects, they reside in our business layer, and the entities are just things that we use inside of our DAL to populate our business objects – that’s it. The objectcontext itself acts like a data access component, like SQL client, we only use it in the DAL.Partial – we use techniques like exposing queryable objects. So, we’re not exposing the object context, but we’re going to expose the queries themselves. This means we will take the entities and project them into our business layer. We’ll take the hit and say that we actually think entities are a pretty good thing. This will gives us some good benefits.Hybid, of course, is a mix and match.
  • So, this returns an instance of a custom class, not an entity from the entity framework.Why?Simplifies our queries. I can still reason over the conceptual model, but only in my DAL.I can have POCO. My custom classes are just POCO. All I’m doing is using the entity framework to fill this.It’s ORM and database agnostic. My application has no EF rerefences.I can go to the DAL and show my DBA that these are all the possible queries that will be executed against the database. Go and optimize your queries, or whatever you do.Cons-No change tracking or identity management. Beucase I’m projecting to my custom class, I’m going to have to do something else have specialized update, insert, and delete methods where I tell the DAL what’s change. You’re going to have to do that yourself. That’s not great.There will also be additional object materialization. For every record in the database, you’ll have a entity and custom class representing that record. And object materialization is the most expensive part of any ORM.Lastly, and the big failing with this technique, is the lack of query composition. No ability to write queries in my business layer that are knowledgeable about my schema. You can write LINQ queries in the business layer, but they will only translate into Ienumeragble – there will be no special optimization that will translate it into a call into the database.
  • IEnumerable – which is a list - instead of returning a custom class, return the entity itself - discrete set of queries in the data access component, entity classes generated for me based on the database design, and there’s no extra step of object materialization - don’t have the ability to reason over the model anymore; returning a list, which is not queryable; you can enumerate over it, and LINQ will understand that, but it’s not queryable – e.g. no optimization. - get full change tracking and identity management – so this would give a complete update - the big difference is that the object context remains in the data access layer, and is not exposed to the BLLIQueryableMaintains the lifespan of the object context, but instead of a list it now returns IqueryableIt returns the query itself, not the productsSo you can no have optimization when reasoning over the modelYou can also bind richly to controls while using extension methods in LINQ that modifies the queryNot perfect; while iqueryable is a nice interface, however, im’ still only talking to IqueryableWhile that’s pretty good encapsulation of the entity framework – not exposing the object context or object query – just the entities themselvesAnd with partial classes on the entities, you still have a lot of flexibility and use composition instead of inheritance to pull in additional functionalityHowever, can’t do eager loading - This is very specific to the EF, and iqueryable is a generic interface across all queryablelinq resources – but it doesn’t understand the include statementObjectQueryThe object query resolves this by returning the ObjectQuery instead of ienumerable or iqueryableNow you can use the include statement – this will give you eager loading capabilitiesProsOther than the first, you get full query composition; if you’re using the EF, you want this – this is powerfulWe’re not using object context outside of the DALWhen using ienumerable or iqueryable, it’s pretty easy to switch to another O/RM if requiredYou get change tracking – meaning it knows the correct sql to project when calling save – and object identity – where I have two variables, queried independently, that point to the same reference; even though it looks like two different variables, they’re the same; this is important with change tracking, as you wouldn’t want to have a concurrency violation with yourselfConsUsing the entity classes of the entity framework throughout my application; this means I can’t have a different base class, and all my logic gets stored in partial classes, probably custom error handlingIt also means that it’s hard to know where all your SQL queries are
  • Development Approaches- Model First development – We’ve added functionality to the ADO.NET Entity Data Model designer to start from a Model and then have T-SQL and customized code generated. - Testing applications that use the Entity Framework – Along with the patterns above we’ve added an interface, along with guidance, that enables better testability of applications that use the Entity Framework. Architectural Concerns- Persistence Ignorance – Enabling developers to use their own classes without needing to introduce interfaces or other elements specific to the Entity Framework. Check out the POCO Series here. - Applications Patterns – Discussing patterns like the Repository and UnitOfWork patterns with guidance on how to use them with the Entity Framework - Building N-Tier applications with the Entity Framework – Adding API’s and templates that make building N-Tier applications with the Entity Framework much easier.Entity Framework Improvements- Customization of Code Generation – Integration with the ADO.NET Entity Framework Designer and T4 Templates in Visual Studio to provide developer controlled code generation. - Small things that make development of applications simpler – Adding things like Pluralization and Singularlization in the model, lazy loading, and more stored procedure mapping make building applications that use the Entity Framework much easier. - Customizing Queries – Adding support for existing LINQ operators, recognizing a larger set of patterns with LINQ, writing model defined functions along with the ability to use these in LINQ, and a number of other ways to create and customize queries. - SQL Generation Readability Improvements – Improving the readability, along with TSQL performance optimizations, of the generated queries to make it much easier to understand what is happening
  • ADO.NET Entity Framework & Your Data Access Layer

    1. 1. ADO.NET Entity Framework & Your Data Access Layer<br />Wade Wegner<br />Architect Evangelist<br />Microsoft Corporation<br /><br /><br /><br />
    2. 2. Agenda<br />What is the ADO.NET Entity Framework<br />How do you structure your DAL?<br />EF == DAL<br />Full Encapsulation<br />Partial Encapsulation<br />ADO.NET Entity Framework 4.0<br />Existing Questions<br />
    3. 3. Object Relational Mapper<br />What does it do?<br />Persistence<br />Querying<br />Manages transactions<br />Manages concurrency<br />It’s a tool<br />CRUD<br />Query model<br />Mapping<br />
    4. 4. Entity Framework<br />What does it do?<br />Persistence<br />Querying<br />Manages transactions<br />Manages concurrency<br />It’s a tool<br />CRUD<br />Query model<br />Mapping<br />
    5. 5. The Entity Framework is an O/RM<br />
    6. 6.
    7. 7. Data Sources<br />User Presentation<br />var apartments = <br /> from a in db.Apartments<br /> where a.State == “IL”<br /> select a;<br />Business Logic<br />Data Access Logic<br />The ultimate question<br />Where does this go?<br />
    8. 8. Separation of Concerns<br />High Cohesion<br />Loose Coupling<br />
    9. 9. What if there was no DAL?<br />Is the EDM our DAL? <br />EF Entities? Are these our business objects? Data Transfer Objects (DTO’s)<br />What if we wrote LINQ queries directly in our business layer?<br />Separation of Concerns?<br />High cohesion?<br />Loose Coupling?<br />
    10. 10. Option 1: Entity Framework as a DAL<br />var bo = new CategoryBusiness(); <br />bo.Load();<br />this.categoryGridView.DataSource = bo.ActiveCategories;<br />UI Presentation<br />var db = new AdventureWorksEntities(); var activeCategories = <br /> from category in db.ProductCategory             where category.Inactive != true             orderby category.Name             select category;<br />Business<br />Data Access<br />SS<br />MSL<br />CS<br />Entities<br />Business Objects<br />Forms<br />ADO.NET Entity Client<br />ADO.NET Object<br />Services<br />
    11. 11. Entity Framework as a DAL<br />Pros<br />Excellent Isolation from DB Schema<br />Independence from RDBMS<br />Object Services: Identity & Change Tracking<br />Full query comprehension over CDM in business logic<br />Cons<br />Pre-.NET 4.0, “Object First” is not well support scenario<br />Pre-.NET 4.0, Entities are not very pure (not POCO)<br />Can’t easily switch ORM<br />Data validation support is limited.<br />
    12. 12. Validation & Business Logic<br />public string Phone<br />{<br /> get<br /> {<br /> return this._Phone;<br /> }<br /> set<br /> {<br />this.OnPhoneChanging(value);<br />this.ReportPropertyChanging(&quot;Phone&quot;);<br />this._Phone = <br />DataClasses.StructuralObject.SetValidValue(value, true);<br />this.ReportPropertyChanged(&quot;Phone&quot;);<br />this.OnPhoneChanged();<br /> }<br />}<br />public partial class Customer<br />{<br /> partial void OnPhoneChanging(string value)<br /> {<br /> if (value.Length &lt; 7)<br />MyCustomErrorHandler.SetError(this.EntityKey, <br /> &quot;Invalid Phone Number&quot;);<br /> }<br />}<br />
    13. 13. Is the Entity Framework the last<br />DAL technology you will use?<br />Encapsulate<br />
    14. 14. Why Encapsulate?<br />Separation of Concerns<br />Testability<br />Embed additional logic<br />Performance/Control<br />Control ObjectContext Lifetime<br />Control SQL Generation<br />Eager Loading<br />How can we do this and still keep the power of the Entity Framework?<br />
    15. 15. Encapsulation Approaches<br />Full Encapsulation<br />EF Entities are merely a DTO used in your data access layer.<br />ObjectContext is a Data Access Component<br />Partial Encapsulation<br />Expose Queryable Objects<br />Encapsulate ObjectContext<br />Hybrid<br />Mix & match as appropriate<br />
    16. 16. Option 2: Full Encapsulation<br />Return an instance/collection of Custom Class<br />Pros<br />Simplified Queries<br />POCO Objects <br />ORM & RDBMS Agnostic, No EF References<br />Discrete set of SQL Queries<br />Cons<br />No change tracking or identity management<br />Additional Object Materialization<br />No query composition: secondary LINQ queries are just enumerating.<br />
    17. 17. Option 3: Partial Encapsulation<br />Three techniques<br />IEnumerable<br />IQueryable<br />ObjectQuery<br />Pros<br />Full benefits of CDM<br />Query composition<br />Simplified queries (Navigation vs. joins)<br />Some independence from ORM<br />Object Identity & Change Tracking<br />Cons<br />Use of EF Entities has implications on Business Layer.<br />What are all my SQL Queries? Hard to answer.<br />
    18. 18. Three DAL Options<br />EF == DAL<br />Full Encapsulation<br />Partial Encapsulation<br />
    19. 19. Entity Framework 4.0<br />Development Approaches<br />Model first development<br />Testability<br />Architectural Concerns<br />Persistent Ignorance (e.g. POCO)<br />Application Patterns (Repository and UnitOfWork patterns)<br />N-Tier applications<br />Improvements<br />Customization of code generation<br />Pluralization and singularization, lazy loading, SPs<br />Customizing queries<br />SQL generation readability & query improvements<br />
    20. 20. More information<br />ADO.NET team blog:<br />MSDN:<br />10-4:<br />