Entity Framework Code First End To End

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
let's uh let's go ahead and get started we can talk about entity frame or code first in this session my name is Sergei barspin and work for Tyler technologies among Microsoft MVP used to be data platform which is for entity framework used to belong but now all those ten areas get a reshuffled I've been working with entity framework since beta one larger wine I guess almost five years ago I think and I had production project an entity framework by March of the following year so within about six months of entity framework going RTM we have a production project very sizable one but five six hundred cables at that time live in production so that's why I'm really excited about entity framework and everything that I might be talking about primarily because I feel that you fill the niche where other Microsoft product really don't play and before entity framework came out a Microsoft did have linked to sequel and which is a which was a Nokia product and okay om or object relational mapping solution but the biggest shortcoming a link to sequel was the fact that it only worked with sequel server whereas entity framework is much larger abstraction hence it works on top of any database engine out there at least at this point it does so anything the semi widespread somebody already wrote entity framework provider and under the covers its using provider model thus you can plug in virtually any data into it in the first graph it was a relying on custom object types so when you work with it the the object that were generated or the entities that were generated there were of custom types so the piston of entity framework v1 code was not as great of a story as one could hope for so since cod4 scheme and which was about three years ago give or take their problem specifically was solved at a higher level entity framework solves a whole bunch of problems so it reduces the friction between dotnet code and the database code in other words you talk to your database object through dotnet objects and all the execution is sort of transparent to you in case of code force which is what we talked about today do you don't have a custom objects that you have to inherit from so essentially you're right I play all CLR objects and then you map your entities to it one thing that happened recently is that entity framework II became open source and I think you almost have to mention it from a perspective that some people might assume that the commitment from Microsoft has been reduced which is definitely not the case the primary goal of going open source is to be centrally open to criticism as well suggestion and participation as well as sharing the information about the design session and so forth public so as other developers with developers can participate better in entity framework going forward suggest futures both for features if you haven't done that and you have you want to see there is user voice but you can also vote on codeplex where you can also download incidentally source code for entity frame so if you ever want to know what's inside of it now is the time one big thing about code first is the fact that it follows conventions in other words you can specify very little in your code and entity framework will make assumptions about your intentions and produce the database if you're using a database creation features of entity framework or you can talk to an existing database either way it will assume what your intentions are and that's really what convention model is all about and that's one of those things that increases your ROI really when you work with that entity framework nonetheless it has another big feature which is a really essential when you're working with a technology that is heavily convention based because sooner or later you have to break out of conditions sooner or later you'll encounter use case when conventions do not work and that's really what configuration options in a tt framework are all about they allow you to drop a level lower and be as explicit as you want to be with specifying your entities and does specify the scheme if you've seen a demo and I think by now most of you have seen at least one asp.net MVC demo when somebody creates code for context scaffolds the entities directly around it and then you have a working website and that's one of those things that I really want to kind of bring it to foreground during this talk and talk about pros and cons of that approach in alright code both ways and you can really judge for yourself but what I'm partially advocating is entity framework is the data access technology it's not a UI technology so personally I suggest everybody don't use it in that way and granted with small projects or even prototypes I really don't see any Hartmann if you develop in a large project with maybe 10 20 years lifespan and you have hundreds or thousands of screens sooner or later that you will encounter and the issue with you genetic framework entities as your business object and it will make your maintenance much fun so we're going to talk about that stuff in the process hence I put the slide in there just to kind of illustrate what you can do with the entity frame or what you want to do with entity framework that's a different question that is on this slide and I'm advocating using it for what it was designed to be used which is data access typically you could use all the abstractions their entity framework exposes like DB context direct it certainly could however most people would recommend that you wrap it and you hide it from your business logic or service layer code the idea being then you will have more flexibility in changing and the simplest example is if you're in the big app your entity framework or just find probably 95% of the time but if your user base grows or you have hundreds or thousands of concurrent users requesting data in the specific way what you might encounter that you will hit that scalability ceiling when it's simply you need to squeeze another 10 milliseconds out of that query and you can't and to me the idea of encapsulating entity framework behind some kind of a facade is so that you can all that use case without having to change UI or business logic all you have to do is change your data access layer right one store proc I'm not talking about rewriting your entire data access layer simply replace one method that was using entities that now will use store products but returns the data in the same shape so your changes with proper encapsulation and layering are going to be more focused and they're not going to be bleeding all over your applications and as far as patterns go to me you can pick whatever pattern you want most most people seem to go toward repository pattern however if you read some of the definitions of at least a few of those patterns I put down you will see that most repositories I kind of lower the line between multiple patterns at least the way they're described in Martin Fowler it will see probably bits and pieces or at least able gateway a row gateway maybe in parts of active record if you use an entity framework from a desktop app so you will see probably any part of it we're going to call a repository for the purposes of this demo and now the strategies I'm going to pursue and we're going to jump right into just simply writing code and because what I want to do is kind of write the code from scratch and to illustrate if a little effort it takes to use code and what benefits you can get out of it even within a linear period of time so the strategy and this is really broad but I'm going to use it for my demo as well I'm trying to separate my entities from my data access layer in other words I don't want my entities to know about my database at all moreover I really don't wanna I don't want to use attributes as much even though I'll show how to do that because attribute is I kind of a slippery slope toward dragging UI pieces into your data access a simple example is if you're writing a b c m and you want to use a remote attribute for example which is something you can use any different will obviously ignored but NBC will pay attention to it so if you're exposing the same object in both layers all of a sudden you have to reference MVC from your portal project so you by accident you can invoke some other specific MVC function and with almost without noticing so what I'm going to try to do is structure my solution in a way that it separates all the layers into projects when you do that you will inevitably find yourself writing the same class twice once to be used as an entity in the other time used as a business object or inference to return from caneva your business object or service value whatever the case might be nobody likes to write a ton of code so my suggestion would be if you starting with data access you can always write pretty quick code generator that will spit out your assembly into classes and then you can use something like auto map and use just one line of code to pump the data from your GTOs which is what they are in case of entity framework into your business life and I'm not sure if we get around to that I depend how much time we have but while we're on the subject all my slides and the full demo that's using all the features we talked about will be available for download and I'll give you a URL on the last slide so I think what I'm going to do is jump into code at this point and we're going to build something small but it should show you how to use entity framework really from the ground up which is what I'm trying to do in this demo and I think we have enough time to do all that so we're talking two projects data to me is going to be where I'm going to house my entities or my poco objects I'm going to use with entity framework and what I'm going to do is build something like a small rolodex where I have people and I have companies and each portion can belong to multiple companies and to illustrate relationships I also am going to add a type portion type and I'm going to add one more class to illustrate one more concept which will become clear in just a few minutes I'm just going to call it address for the time being so let me jump to person type so the idea behind this poco class it will be my entity that will map to a table to map it to a table typically I would need a couple of things that are typically going to use I'm going to have a primary key column and in my case X I want to fix - in my case it's going to be an identity column since I'm going to work with a sequel server and I'm going to call a portion type ID and all I really needed together in the cellar it's a poker class I really don't need to get fancy so right right away we just encountered a convention that entity framework has that convention is specifically designed to figure out which column is my primary key column and that's what I was talking about because I have a column or property in this case they start with my class name and ends with suffix IDE entity framework all immediately assume that this specific column is my primary key and because it's an integer in sequel server it'll make it a primary key column and identity column at the same time and the other thing I want to do is create a name so now if I'm going to generate data based off of this you will notice that another convention is going to kick in and my column type is going to be in Bar Carmack's in sequel server which is really not what we want say I want it to be 30 characters long now I need to drop down and tell entity framework a little bit more information so one way I can do that is using the attributes and all that all I need to do is reference data annotations and we'll bring that in and then I can give it a link so this actually works and that's one way you can figure it again in my opinion you don't want to go this route unless you write in something small or if you using product already prototype in something if you if you have a very large app I would recommend that you configure your stuff in a different way and you separate your Poco entities from data access logic which is where my schema resides really schema does not reside in poorer classes it results in data access layer and to do that I'm going to go ahead and create some configuration classes in this case I'm going to Suffolk someone with a map and just make this class public and this is a basic configuration type that will inherit from entity type configuration base class of type or person type and I'm going to import all the namespaces here and we should be good to go now to add logic to entity type configuration and that's the easiest way for you to configure all I need to do is flip back I'm trying to specify some information about the name property and it's all strongly typed fluent API and here's my name property that I can pick from the intellisense and now I can configure whatever information I might have for example I want it to be a maximum 30 characters long which is needed and there's another at another method that could use code required what that will translate to is is going to make this column in sequel server non null and since I've keep mentioning sequel server it's going to be the same case really with any other database provider that supports code first so you can use this fluent API and build this all the configuration for single property in a one line of code a couple of other useful ones you might find is Unicode so if you build in an app that is not English only you might want to specify your columns as Unicode columns and by default they actually are you nickel but if it's English only app you can make your app a little lighter and make your database all smaller if you said is Unicode to false something like this and then you simply just continue doing the same thing for each property if you have a naming convention that doesn't follow the one I picked which is person type ID actually it'll also work like this I can call it just ID and it will still work but if you want to drop out of that specific convention you can always jump down to configuration in this case as well and specify that the key is my person type ID problem typically I don't write code that is necessary so I'm not going to write it in this case either and so by creating these maps you can configure your database by simply specifying all the methods for each property now while we're on this topic let's jump back to other classes and fill in couple of details so in this case I'm going to add another property and I'm just going to use snippets to cut down on some time and I'm just going to add fortunately not going to write too much so now what I'm trying to do is also establish the relationship and this is how easy it's going to be for me to specify that each portion has a type that is assigned to that person it could be whatever friend so to specify the relationship we use exactly the same property type and this is really how we specify the relationship so if I want in this case one-to-many relationship meaning that each type relates to many people but each person only has one type assigned to them all I have to do is specify portion type in a portion class and that's it so there is one drawback to this and this is how we're going to solve it person so this is nice and easy but say you're trying to post an update say from a web app and you need to establish this relationship if you also don't have an integer property like portion type ID you can just set to whatever your site drop-down belongs to you can have to write quite a bit of code you would have to say person that person type equal new person types that have at least primary key on them so your food becomes kind of worthy so to avoid that issue whenever you establish a relationship my advice is to set up both of these pros parties and to signify that it is one too many I'm going to also specify the reverse relationship or divorce end of it with this way the so now each type has a collection of people associated with so now I have one-to-many relationship now to specify explicitly in the configuration I can add a person type class person person map which is going to inherit from entity type configuration or portion of course and we're just going to again importa and port all the namespaces and then override the constructor of death and here's I'm going to specify foreign key relationship I can say has meaning because now has a as required because my my portion has person type which is a required class and reversal is that each portion type has many people and then I can specify foreign key is going to be portion type ID so now I fully configured one-to-many relationship as well as specify that the actual column that establishes that I could set is the person type ID so this is one-to-many relationship one thing I'm going to show you right quick well when this subject is the virtual keyword and typically you want to decorate your Association properties of navigation properties but sure when you want to call them with a virtual keyword and let's let's talk about that for minute when you use virtual keyword you will enable enable entity framework feature called lazy loaded so whenever I retrieve say a person by default the type isn't going to be loaded but I can simply type dot portion type and the entity framework using that lazy loading feature will go on fly quarry the person type table and return that data to me which is really really cool feature because you don't have to worry about related data in some cases you will load it as you see fit what enables that lazy loading to work is the virtual keyword because that will enable entity framework to create what's called a proxy type which are runtime classes that will adhere it in my case from person type so if I query it I will see that class created on the flag and those are typically called dynamic proxies dynamic proxies is what enables lazy loading while we're on the topic of lazy loading it's fair to mention that lazy loading can get you into performance problems and give you a specific example I'm sure you'll see why say I'm going to rebuild build a webpage when I you numerate through you know 100 people and for each one I will print a name and I will print the type name so if I simply gonna say give me a list of people and I'm going to do for each loop and I'm going to print or create a label or whatever for the person name and a type name the code would be person dot type dot name that innocuous code lecture result in the qualifier then against the sequel server so what all of a sudden you have instead of a single query to build a page that returns a hundred rows you just file a hunter than one quarry to build that exact same page so lazy loading is a very very powerful feature but you have to continuously think about what you want to lazy load and what you want to eat and entity framework allows you to do either eager Logan as well by using a dot include extension method on a DB set that will allow you to explicitly include the data so now that we got one-to-many relationship how do we create many to many and this is just as simple all we need is a primary key here again I'm just going to add a name property now I can establish a relationship many to many relationship between people and companies and as you saw in this specific example it's pretty much self-explanatory what we're going to do here is going to be I collection again or person it's going to be called persons and then we're going to go to portion and we're going to do a reversal and this is going to be I collection of company companies and that's really all we got to do to build this many-to-many relationship again I will use keyboard virtual to enable easy loading but you really don't have to so all these classes I just wrote they're called what school they're essentially entity classes or entity types the reason I call and that is because they map to my tables but I don't have to write classes that map just want to want to tables so let's see how we can do that one of those ways we can do it is by using an additional class in my class in my case this is going to be address and I'm just going to add a couple of properties here to demonstrate the point I'm going to add street and state a bunch of stuff as you can see the main difference between a complex type in the entity type that complex type does not have a key in other words it's not going to map one-to-one to a table instead it's going to map one-to-one to a subset of columns so to enable that I'm going to draw two portion table add one more property to it call address when you use complex types you want to be a little bit safer and to do that you want to create an instance of complex type in the constructor otherwise you may run into null reference exceptions at some point or another a developer is going to forget to initialize it so if you put it in a constructor you don't need to worry about it and a real power of complex type comes from reuse so I can put the same complex type also on second table and now what I get between those two tables is consistency so now both of my classes share the subsets of properties so now question it'll map to a subset of columns it wont map to a table so we'll see that in just one second once we run that in you'll see what it looks like so to do that there is one more thing I want to do and I'm going to add one more class and we're going to call it address map and this is how we will provide the configuration for complex type it's going to be instead of empty T type configuration it's going to be complex type configuration again is going to be a generic type of address and you already seen what kind of code we write so I'm going to just do one D API between complex types and entity types is exactly the same and so I'm going to say state only has two columns and then there is one more thing I want to do oops I want to specify the column name and I'm just going to call it state so let's talk about that for a minute just column names in general there is another convention that if you like you don't have to specify column name but the way complex types are interpreted is your column name is going to be your class underscore property so the column name in sequel server will be called address underscore state which you might like or you might not so if you don't like the convention what you want to do is specify column name explicitly so this explicit column names and you can actually do exact same thing with table names as well it comes in really handy when you're trying to put entity framework on top of existing database especially like I said eight of it especially the one design in the 90s especially the one that is Oracle and you can just continue on and on and on and you end up with column names like DC underscore one and I know because I've seen I know those databases are out there so when you put in the code force or empty framework in general on top of legacy database you can always rename your columns and what that allows you to do is have much nicer API to work with when you don't have to teach each developer what a specific abbreviated column name in means you can give it a nice business like names so this specific explicit column mapping and explicit table mapping is really really useful feature when you dealing with legacy databases so now say my model is built I didn't create all the so some of my data isn't going to be right but I'm I'm kind of ready to move on and to move on I need to create a database abstraction so what I've created so far our table abstractions now what I'm trying to do now is to wrap all those table abstractions inside a database 1 and to do that all I have to do is inherit from DB context which is code force database abstraction type and to write one you really need to write a whole bunch of code I'm almost done the only thing I want to do is override the constructor and the only reason I want to do that is because I want to specify the connection string and I can use name equal connection string syntax or I could spell it out completely it's up to you if you use name equal entity framework we'll pull it out a web config or app config depending if you have web app or a desktop app so now the constructor is done the only thing I want to do now is is tell entity framework what tables exist in my database this is just as easy and you simply specify them as G be set of whatever your entity type is so in my case I will expose person then what do we have well have company and then we have person type I think that's it so now if I build that now what I should have done well as you notice I did not do anything with the address because it does not map to a table so no what I should have what I should end up with if I if I create database off of that is a database with three tables with some one-to-many some many to relationship and some subset of columns in two of them map into my address so let's see how we can do that so what we can do is simply touch the DB context and by touch I mean fire one query and if the database does not exist it will be created so let's let's start with that and then we're going to go farther so using our city eight new context and now I can do two things I can do something like this var quarry is equal to C key X dot and we can see my people in here persons thank you wrong class okay I see good enough Thanks so now I created my context and I should see people in here so I can do something like this I have to list really I wanted to show you this because this illustrates another important point of entity framework called delayed execution so if I write something like that people and then in here I would say var count equal or eaglecam oops let's see we're going to say iqueryable or what did we have for some type if I do something like this and I would say Cory count what I end up on this line is an exception and this really illustrates the point of delayed query execution in other words my query isn't fired against the database until I access results that and I can access result set by issuing like count or two lists or two array or I can do a for each loop as soon as I touch the first row is when the query is going to be executed so when you are using a context from say MVC app and you want to return the query but then you numerate the core inside the page for example you don't want to dispose of that context right away you want to wait for the entire process to complete for results to be processed before you fire dispose on your context and you do need to fire this post because that will release the connection string I mean the connection object back to the pool so you always have to play nice with entity frame or just like with any other deal in that case it's not different the dispose is something you have to call when you're done so let's let's kind of let's take that out change this a little bit and let's see what we can do to initialize the database here I can also explicitly initialize database by calling database dot initialize so if I run that and I don't have my three finish my context contacts database year so if I run this this code should here and if I have if I have not made any mistakes which is highly unlikely and then the database should should be created the air comes up because I have a controller yet defining it's like a plain app so if I look at my structure now I see my basic table structure my portion table which will have a type ID which is my foreign key you also see that my conventions actually did not take and that's because there is one step I forgot to do and we're going to do it the right way what I need to do before all this configuration will work I have to override on model create in here which is the method that provides some hoops for you to inject your own custom logic into the DB context and you can say model builder dot configurations dot add and now we can do person map and then I can add all other Chinon remember what all they are I think there is a person type map a goes person type map and I think I have addressed map so if I run this again because I dropped a dated database it should recreate it again with my fixes so let's see what what's going to happen here okay I think it's done let me refresh this and here's my context database and hopefully this time so now it looks nicer should I have my state so my configurations took that illustrates another important point in production I don't think anybody will like if you drop the database to replace a column and some people might like just not like it's highly unlikely and that's why you need to use a very very important feature that entity framework has since 4.3 called migrations and migrations allow you to maintain database schema from c-sharp code and I'm sure everybody at some point had their own routines for schema evolution maybe use scripts maybe use SSD key maybe you third-party tools like Red Gate you have to maintain scheme like there is no way around what migrations give you is ability for developer do it all in one place so let's uh let's start using migrations say I need to add a column to my portion table called data so I want to know when this specific portion was inserted into my database so to do that what I want to do is enable migrations on my schema first so to do that I'm going to go to package manager console and select my project that houses my dbcontext entity framework at this point we'll find it and enable migrations form but to do that I use power PowerShell commands and I run enable migrations our main mistake should be plural migrations that might work a little better and I can stop debugging and now let's see what just happened the only couple of things got created here one is my initial migration which is the database as it existed when I enabled migration so what migrations did is scaffolded my database using the my connection string that I specified so it scaffold in my database figure out what tables I have and created what's called the initial migration now I can compile this point it to a different connection string and will recreate exact same database form the other thing that it did let me pull up system tables on my database it created this system table hidden from me called migration history and this is the magic behind migrations so there is one already in it and that's the initial migration and the reason it was pumped into it is because my data already exists on my machine however if another developer gets latest they don't have the database all they have to do is run this code in and we'll create that database for them to do that let's let's update a table so let's pick a person one and let's add a call from date/time we're going to call it date edit so there are a couple of ways I can do that I can simply enable autumn what's called automatic migrations which are disabled by default and let's talk about automatic versus manual migrations for what automatic migrations do when you run it it's going to compare your c-sharp codes literally your classes with this schema in a database and then it's going to spot the differences and then the economy in no specific order i all tried to determine the order but for the most part you don't have control which is really easy to do because it cuts down on the amount of work you have to do so lets enable this for a minute and what I'm going to do there's two things I can do so on let me clear this one thing if I'm a developer and I just edit this column I want to update my database and start working on my feature that's really what I want to do so what I can do is called update database without parameters hopefully spelling it properly and like I do and what that's going to do is create a new automatic migration figure out what the differences are and I create hopefully data edit column here so it just happened of course the column is not novel and that's another convention that the entity framework has non malleable type which are structs like daytime or trim it is like ins in dotnet frame in dotnet framework there are not malleable types so because entity framework wants to match the types to sequel server or any other database engine for that matter what it's going to do is create non malleable column now you have a big problem because if you have existing data you have to put something into that non audible column to make your database engine happy what entity framework does it magically figures out what the default value would be so let me look to see what it did for my table of course I didn't have any frozen but what it would have done would have put 1 1 1900 I really don't know why but that's the date you would have ended up with if it was an integer based Colin would have been 0 really any number would default to a 0 string however is inaudible type in a dotnet because you can sell it to know so those string would be novel by default and left as no if you want a Markham is required and we talked about that specific method in entity type configuration is required on the property type configuration class then we'll the market is not novel and would have shot an empty string in there so some of those defaults may be ok some of those defaults not something you want so to illustrate will happen let me a couple rows here it would make a novel call it would be date time so if the question was let me repeat that what would have happened if I define my property like this Nala build a time so at that point it would have created an audible column of type date time with no default value for because it's not me at that one so now let's jump back to this let me add add a row one one nineteen should work so this is what it would have looked like if I had a row would have created this is a default value not something that I want so let me create another property also date time and I'm going to call it last modify so now what I'm trying to do in let's modify is always create is always stamp the row with the latest date the racket was typed so if I have existing data and I'm trying to add some some new columns into it there is a way for me to specify default value however to do that I need to drop out of automatic migrations because as you can see there is no place for me to say oh by the way this is the default so let me see there is a portion map here so if I gonna do another property and I'm going to pick my new one which is something you would need to do whenever you have the property to your class you have to update configuration there is nothing that says default sum in other words I have to provide the default elsewhere and this is where migrations come into place so what I have to do now is add what's called an explicit migration to do that I type add migration and I give it some name in my case it's going to be person underscore class so I'm going to add this explicit migration the same thing is going to happen my data is going to be scaffold scaffold it and compared to my schema and then my new migration is going to be created and here's the add column which is the only new column from the last time I ran migration in here however you have defaults so now I can do defaults in two ways if it's an integer type for example I can specify default of value equal to say I'm adding new foreign key a pre-loaded sum 0 1 to values in it and I want to default existing data to something instead of 0 you can explicitly specify default value for existing data or in case of date/time the constant really does not make much sense and at that point I can use default value SQL which is the string that's going to fire whoops get data and get string which is a simply a string that will be executed on a back end so it's not going to be interpreted in c-sharp code it's going to be interpreted back in and the get date is a function that sequel server has and it will populate my new column with that specific default value now we talked about updating database from a console however some developers may not like it so you have a group of 10 people they already find migrations age you grab that maybe you don't want to sit there in executing one by one you can do update database and lower all to the latest version but if you do in rapid prototyping what you really want to do is just run it and have it magically do the work in production you have couple of options there so if you have a DBA chances are he or she will ask you to provide the script instead of just running your database and doing something with the most divisions don't like that approach so update database has an option called script so you can go update slash database - crap and I can do a hit tab key and I'll give me an option and in this case I want to create a script so what this will do is do exact same thing else careful the changes but it won't apply them to my database instead is going to create a script that is going to that you can give to your DBA and you can run it like you can point your connection string to say your production snapshot get the latest around that and here's your script that you can run against production database so they don't have to do the migrations however if you're in developer you want to really kind of make this process to have a little bit less friction and in that case what you want to do is you use what's called an initializer so let me add an initializer here and I'm just going to call it in it and I'm going to in here it again from a base class system dot data dot entity dot migrate database to latest version so this is my initializer and it takes two parameters it's going to be my context which my I misspelled it and my grace and my other generic type parameter is going to be migrations dot configuration it's going to complain about one thing and what that is is the scope incompatibility my initializer class is public but migration is internal so for now when I just change it to public as you can see in just a few minutes if you write in a repository chances are you want to make this one internal instead of making your migrations public thus you will hide the internals of your database workings from the consuming code from your web for your business layer or whatever else it might be you really don't have to write any code into initialize all you have to do is define the class you could write some code and there is an override a has a or not in the initializer original code there is a code in migration which I meant to show you and it has a seed method and I think I didn't have it in here but it has a seed method that would allow you to pump some data from the migration into your database so coming back to my initializer all I have to do is set that initializer somewhere before you touch County so if it's a web app it's probably something you want to do in global si X if it's a desktop app you just do it in a star that you want do it before you have attached the database that's really the only rule and you set the initializer on the database object set initializer and you simply create a new instance of mine it so now I haven't updated the database it still should not have whatever that column I added let's modify it's still not there all I did is set up the initializer I'm going to put a breakpoint here run it through let it execute and now if I'm going to go and browse my table again well I will see that my data is populate and actually has my default value apply so the key here is you can reduce friction during development process by simply updating your database first time you run so if you want to make it a design or debug time only you can always do something like this pounding debug and wrap this whole context here so if I'm worried in production I'm not going to implement any migrations because my DBA will have run the script that way your app when it starts up is not going to start altering the schema in your production database of course you could do that however there are a couple of things you have to consider one is security and meaning that your app has to have has to have enough rights on the database to alter the schema which means it almost automatically has to run under DB on if you want to do that and most DBA is simply not going to let you do that so however in during development you will see that it will greatly reduce friction for developer they simply get latest run database up-to-date very very easy there are a couple of things that look very easy they may not be in multi development environment you already see that if you have ten people on a team it is possible that they may have some conflicting changes that somebody will have to resolve so they create maybe a hundred migration then you have to sort through them maybe they use the same name for whatever reason both of them so that there is some amount of work you may have to do but it's no different from doing the exact same work if you use some it's something like SSD T or red key you still have to reconcile the differences between multiple developers however the migration to me is really the way to go the only thing I'm going to say about it with sequel server not going to have any problems if you use it any other provider then you have to contact your provider to see how much they support so if you using like Oracle or Dell art or data direct or my sequel you have to read to see how much they can do for you and if they can't then you're back to writing scripts but in sequel server since this is a Microsoft conference I'll just work there is really no extra code you have to write now let's do that because we're kind of running a little bit long time and what I'm going to do is create like a small repository to illustrate the point and then I think I'm going to jump to pre build slides because we only have about I think 15 minutes to wrap it up so let's let's see how we can explore dbcontext API to create a repository class and part of it is a philosophy I guess so I'm going to create an interface first and in here I'm going to do writable operations only and we're going to talk about read operations in a second so we can do T in third of TT item and then we can do go save same now other and the only thing I have to do is if I'm willing to build a generic class then I need to give it like a genie a generic constraint it's a class because entity framework otherwise is not going to like you very much so now let me just create update insert and delete and the only other thing I want to do is what I already talked about I want I disposal so what I'm trying to do the idea for me being is I want to build a generic repository they can in here that can in here it many times but not have to write basic to create update delete operation all I would need to dry this select and what I want to show is how easy it is to implement this using entity framework so we're going to move it to another file then we're going to implement members then we're going to make it public and then we're going to give it a generic parameter of T context and then I'm going to provide some generic constraints which is DB context and new so now I have some resemblance of generic diction I mean generically possible now to do this pose first thing I need to have something to disposal so I'm going to create a property here first I want to create project I'll just going to make it protected because sooner or later you will need to expose that to your inherited classes actually it's going to be private set not private yet so now what I can do is in the constructor of my repository I can say context equal new country that's it in this pose I'm going to say context dot this poll and now the in third poem just going to write an insert and kinda move on with the demo how easy it is to write an insert one line of code I can say context dot entity entry item dot stay equal edit and then I can say if say now context let's say that's it literally one line of code they save now is more of a convenience so you can do one line of code in in your class and of course one thing you might want to do here is do in save this way you can do batch update context let's say change actually a return context on Save Changes and so I can do batch update so it's important to to know and I need to return right it's important to notice that I can easily abstract that out into single method and call it from all of this with just a different state but I'm not going to do that in attempt to save a little bit of time that's it so now I have a generic update repository now toad let's talk about philosophy for a sec what's wrong with this I numerable of T select of T that's it something like that let me flip back here we're going to return context dot set of key I need to add generic constraint here and the same thing or in seas in the wrong place one sick and what else so no trauma disco let me create an instance of this repository again and let's say three and out of the arrived type we're going to call it context or evil or you don't need this but what I do need is this context the little data make it public so now from my consuming code I can change this to context or Ipoh contact repo and then I can say C TX dot can't not come text I should have been protected select of portion tight and then I can say where one the first type ID greater than zero dollar email inaudible so here is a heater slide problem again it comes back to philosophy you can do it certainly but there is very couple of issues with it one if your GPA comes through and say hey I'm trying to put some indices on portion type can you tell me how you Cory's this data guess where you're going to find that code everywhere everywhere you touch that set so now you're where clauses your info lap your order buys a lot of the place it's very very hard for you to figure out how you how you operate on this specific set and that's why I would advocate against doing something like this because it to me again my personal two cents it sort of defeats the purpose of having repository because you're not really separating consuming code from data access code they are intimately aware of each other and the other problem that you have what if my DBA comes to me and says hey by the way on portion type class we're going to replace all crud operations in select with a store crop you can swap it out you have to literally hand down every instance of this code and replace it all with store protocols somehow and then you have to write all the store products to make sure you have the right where clause in the right order by and the whole bunch more work so to me in my opinion again I don't particularly like that approach it doesn't take that much effort to write a simple method on the class that does is select so if we want to look to see what it looks like here's my contact management repository and I have get contacts type so in my case I have criteria class but it doesn't really matter what I'm what I'm saying is give me all the contacts based on some criteria class so in my case I'm specifying fourth column and harmfulness and you know Sandin and so can those kind of things so I'm using dynamic link here again you can quite as easily say have a method says get contact types sorted by name is sent and then descend so you write two lines of code so the drawback of write two lines of code is negligible you have it done in two seconds flat the benefit is your del isn't leaking outside of your deposit it contained within that specific repository and that's really if you can look at that code again I will I will post it however one thing I want to show you is this is just generic in search so if we're going to look at something what I call a service by really more it's it's a pre-clean service it's something you can wrap behind a real WCS or so use it as a service what I wanted to show you is the create method here so if I want to see how I'm doing update count here it's a one line of code that's the benefit to me of writing a generic repository versus specific repository you don't have to write that code ten times it also illustrates another point and it's something I talked about you have to evaluate yourself I mean in my opinion if you have two classes you're always better off you're not exposing your business layer to your del you can also have them both in here from the same interface may be abstracted that way that's a possibility in my case I'm simply using auto map so if you've ever used on a map or it makes it really easy for you to pump data from instance of a class into an instance of another class if they look the same it's a one line of code to configure and one line of code to pump the data it's the kind of win-win one you have a clean separation to you still write one line of code and the only drawback there is a bit of overhead there and if you if you encounter that problem you can always replace that one of code with 10 that explicitly pumped the data from one including that again I would not do it until I have a performance problem the same thing goes with using store products or views which I did not demonstrate which I really want to contact database execute the couple of methods on the database object in enough context that will allow you to call store box and are called SQL query and there is also a command here execute SQL come here so if you want to return the result set you can use this generic SQL query of T and you can do something like person type is really whatever but we can do select star from person types the idea being you can imagine that this is your store prop and this is your return type so what entity framework allows you to do is take care of materialization for you so you simply write store proc you put the name here you map it to result set in one line of code you can you execute opera we use is really the same thing you can pretend that portion type is a view same thing so what you would need to do is define a class you will use for materialization of your result set and that's it and you can use store props and again something I always try to mention is that entity framework is never in my mind all or nothing solution sometimes you need store Pro sometimes you simply cannot get those extra 100 milliseconds you really need there's no way around you know sometimes you will encounter problems like that that's when you drop the store products by the same token entity framework will provide you much faster environment to develop your apps and this is the part that you cannot be if you compare anybody right install proc with somebody who's using the entity framework and you compare productivity it's not even close you're gonna you're going to spend a lot more time writing your Dell than you ever would with an RA which is entity framework ease and RM the only other thing I'm going to mention is a separation in case you want to look at this project yourself as I mentioned before data Porco object like I said you don't have to map one to one you can even instead a portion type here you can say you can have a person info class put it into the same data project it will simply your class you will use for materialization of partial entities and you can do whatever it is you want to do with now the data access is where my repository and the deck context resides and you can keep them on one makes it really easy to create internal classes where you just hide the logic from consuming code by making everything internal and then business is really where my business objects are now it's another run solution so business is where my models are which is my classes they look the same but what they're going to have because this is MVC app our MVC specific attributes including display name goes back to the point do you really want to put a display name attribute on data access I mean it makes really very little sense it will save you a little bit of code to me not enough to blur the line between the L and business light and then once you get done with all that then you have services which hide sort what services do they hide your even repository from your consuming code and at that point if I look in the controller and I look at contact type controller what I will see here is that create an instance of my service and then I simply call update type passing hi to me the goal always is one line of code if you can write some structure when you can do a whole bunch of work in one line of code you just can't beat that so the separation will give that to you of course we want to cut some corners you could change this to eye contact or positive and now I'm going I'm not going to judge I'm not a judgmental person and that's really all I want to talk about me flip back to slides and make sure I didn't forget anything I wanted to talk about we told I didn't mention CQRS but it's exactly what I talked about I want to separate read operations from right operation and I will have a different repository classes for each one we talked about everything we didn't talk about performance quite as much I mentioned lazy loaded they have to be where you can really hurt your performance in some cases lazy loading and the other thing with the code that I wrote you won't run into any update problems you can run into update problems if you write code like this show you one set so I could say var portion is equal C TX dot context portions dot find three what a portion IDs and then write person dot name equal one and you can imagine that this data say comes from a pulls back of the website and it gets in here somewhere so you have person something like this this is a performance problem because this even though you see this code in some demos find actually results in the Select core so all of a sudden to do an update you have to do select force which is really not good so avoid those types of performance issues the other thing we talked about is web environments whenever context starts up for the first time whether you run initialize database or issue for query he has to build this whole humility how much depends on your database size if it's a thousands of tables you may take a few seconds may take 10 SEC hard to say for sure but you if you're running if using any framework and web environment set up your pool recycling so you don't suffer from those performance issues maybe set it to recycle at night and maybe even hit the page to warm it up after that you can use a warm-up module in web talk about separation I will post the slides and the demo project Kevin excuse me have any questions my email address it's also on my blog which is the next URL you can also grab it from the brochure thing and my email would be my first name at last name com so if you ever forget that's what it is I really appreciate the feedback if you guys want to fill out the questionnaires or if you want to give me any kind of feedback on what we talked about or if you have any questions please don't hesitate to email me I have been recording this so
Info
Channel: Sergey Barskiy
Views: 104,447
Rating: undefined out of 5
Keywords: Entity Framework
Id: l3WzYZsN0gU
Channel Id: undefined
Length: 75min 47sec (4547 seconds)
Published: Sat Mar 30 2013
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.