NEXT LEVEL! - Upgrading Our Blazor App With Entity Framework Core
February 12, 2024
• 869 views
blazorblazor tutorialblazor web applearn blazorblazor tutorial 2021razor pagesblazor webblazor appblazor tutorial for beginnersblazor web app tutorial.net blazorasp.net core blazorblazor c#blazor tutorial c#asp.net core 8blazor pluginsentity frameworkef coreentity framework coreentityframework corec# entity frameworkc# entity framework coreC# entity frameworkef core performanceentity framework tutorialentity framework c#
In our ASP.NET Core Blazor build series, we reached an important milestone: It's time to get started with Entity Framework Core. So in this video, I start on the next phase where I walk us through my thoughts about getting EF Core setup in Blazor.
We have more design decisions that we'll need to make after this! Entity Framework in C# is powerful, and I'm only exposing some of it in our Blazor Web app. Will it be enough?
Have you subscribed to my weekly newsletter yet? A 5-minute read every we...
View Transcript
all right in this video we're going to continue on in our Blazer build series and where we left off was about to get started with Entity framework core so in this video I'm going to walk through how I'm setting up Entity framework core for our little blazer app that does metrics tracking and it's kind of interesting because for me as someone who's been using C and SQL for ages now or what feels like ages I don't use NTI framework I write my own SQL queries I've just always done it this way and Once Upon a Time Entity Framework was slow so it made sense to go write your own but now that nity framework has evolved so much it's standard in so many places I'm falling behind so part of going through this Blazer build series and trying to learn Blazer in public with all
of you is also learning Entity framework core and showing you how I'm navigating that just a reminder to check that pin comment for a link to my free Weekly Newsletter and check out any courses that I'm working on for Dome train all right let's jump over to visual studio the first part that I want to start looking at for Entity framework is what I decided to to go with to start and a lot of people are either going to rely on a Microsoft SQL database MySQL something like that but I just wanted to go with SQL light to get going so if I jump over into our social reach project if I head over to the project file you can see that I have Entity framework core and Entity framework core for SQL light as well so like I said the reason I'm doing that
is just to get started keep it simple and because Entity framework allows us to be able to switch the database Tech later I should hopefully have no issues if I want to go change this at a later point I shouldn't have to go rewrite my whole app but here's what I have added in Fr nugate packages and depending on when you're watching this there may be newer versions so please don't feel that you have to use 8.0.1 but that's what I'm using in this video now the next part that I wanted to focus on when I was going through this exercise on my own was designing what the database is going to look like and I started with a code first approach because like I said I'm very used to to writing my own SQL queries and that generally means that I end up going
into a SQL database editor and trying to create tables and things like that directly in a SQL editor so I decided I'm going to start with the record and what I was thinking about is that each of the records that we're going to have in our only table for now are going to represent the different metrics that we have in our social media tracker so we've started off with Twitter and that meant that having something like Twitter followers or your Twitter following that would be something that we'd want to record so that would be your platform ID would be something like Twitter and we're going to have other plugins for other social media sites so that platform ID will change but I also figured that I wanted to add account ID and this might seem a little bit weird because you know for most of
us we only have one Twitter account but I was even thinking for LinkedIn for example I have my own personal page as well as a business page so I may want to have the platform ID separated out from the account ID because there may be cases where there's more than one so that's why I started to pull this out as well I wanted to be able to track the timestamp that I was recording this data at I'm going to keep it in UTC format just a a habit I don't like having anything in local time it just feels like that could be a recipe for disaster in the future and the idea with the timestamp uh I'm thinking that if we're going to be plotting data I want to make sure that I can have a Time range that I'm working with or maybe I
can say organize these data points by time like anything like that but I think without a time stamp it could potentially be hard to navigate just having a big blast of data that's dropped in because if we don't know what the different frequency or the Cadence is for the jobs pulling this data from the Internet it's going to be hard to figure out what's happening when at least in my opinion so that's the idea with the Tim stamp now one of the last things I want to talk about on this dto that we're dealing with is the metric name and metric value and originally when we were looking at Twitter fetching we decided that having followers and following was probably going to be pretty standard but I figured on the dto so basically what we're going to be dealing with in the database that maybe
keeping it a little bit more generic would be helpful and this might come back to bite us because if I just have metric name and we want to set that to followers like technically there's nothing really enforcing right now that it has to be followers maybe with a capital f or a lowercase f or we have subscribers or something like that like there's nothing enforcing the standardization so that could make it a little bit messy but at the same time I figured it might be a good opportunity to keep it flexible at this point in time and if uh as we add more plugins we decide we want to lock it down a little bit more then we can change it at that point and for the metric value I just figured an integer is probably safe I couldn't think of anything off the top
of my head where we would have fractional metrics but uh perhaps there's going to be a bit of an issue with these two things later on but I didn't want to waste too much time trying to overdesign for that now one of the last pieces that I want to call out in here is this social metric ID so this is going to be the ID for this record that we'd have in the database and I want it to be automatically incrementing because I don't want to have to think about it I figured this was going to be one of the nice benefits of just dealing with it in enity framework core but what's interesting is that when I want to go create one of these records so actually initializing one of them I don't need to be able to specify the ID and that meant
that if I wanted to have it all in the Constructor technically this one gets kind of weird if it's in the Constructor because I don't want to pass a value for it but this does need to be accessible for enti framework to work so I did make it a property that was going to be initialize and get only so that's why this one's pulled out separately just because it's going to be dealt with automatically next I'm going to talk about the data context and some of the patterns that I was considering here so depending on your experience with enti framework core you might start to look at some of this and question what I'm doing because perhaps there's better patterns that you're already aware of now for me something that I really don't like about n framework and other designs in general are when we're
forced to inherit from base classes I don't like using inheritance it really drives me nuts it's just a personal preference but one of the reasons that this makes me a little bit unhappy is because when we have to deal with these DB data sets here uh this is the one for social metric which is the dto the record type that we just looked at so this is the table that we're going to be dealing with in Entity framework now what I don't like is that this is a setable property when I go to use this throughout my application I don't want this to be setable in any capacity it's different to be able to mutate the data but I don't want to be able to set this this doesn't feel right to me but the challenge is that in order for this to get initialized
properly through Entity framework this needs to be setable so what I decided to do was make an interface called IM metrics DB context and that was going to be something that I declared up here and if we check it out it's going to expose a getable version of this DB data set and it's going to have save changes async and that's going to mean that we're able to technically add things or query them from this uh DB set here and then when we call Save we're going to commit changes to the database there are probably going to be other things I need to include one of them right away was having it be disposable so that when we create one of these things we can get rid of it once we're done because my understanding with Entity framework is that we don't want to have
a DB context held open for a very long time we want to open it use it close it and move on the last part here is just that this is technically going to be a sqlite implementation of this DB context and that means later on if I want to go move to mySQL or something else I'll probably have a new implementation of this whole thing but it's going to look pretty similar probably aside from this on configuring part because as we can see in here it's explicitly calling use sqlite there's potentially some other other better ways to do this that I'm not familiar with where we could uh perhaps keep this a little bit more generic and then configure it from the outside perhaps but for now I figured this is enough to get going and I'm going to roll with it but that's going
to bring me to the next challenge and that's that if I want to have this imetric DB context used in our application I need something that's going to be able to expose that to us and that means that I need something that can create it I know that there's an idb context Factory that's inside of Entity framework that we can wire up with our dependency injection but the challenge is that it's going to expose something that looks basically just like one of these this whole thing right and it's going to mean that it has this setable DB set on it so I wanted to make my own Factory so that I could have full control which is what we're going to look at next with this metric DB context Factory and technically this one is also a sqlite implementation of this because it only makes
the sqlite version and we can see that down here in this private method where it's technically constructing it but the rest of the code that you're seeing on screen if you're wondering what the heck is going on is that I wanted to be able to ensure that when we go to create the context for the very first time that I'm guaranteeing sort of uh just in time that I'm creating the database so what I didn't want to do is on application startup call Ure created uh which we can see on line 103 here I didn't feel like that was a time that I wanted to call it at I mean technically it's probably safe and it could simply ify this class we don't need this uh this lazy instance here but the way that I wanted to try this out was as soon as you
go to create a DB context for the first time we'll call this we're going to go ask to have this lazy instance evaluated once we're not really using the return value but we're creating a context and with the using block so it'll get disposed and then we're just calling and sure created it on here on line 103 so that means that every time we go to run this it's going to try once the first time but because it's lazy it will never run it again and then of course it's just going to create an instance and return it so this class is a little bit weird but I just explain why I created it and probably as I continue on with this I'll find some better ways that are a little bit more common practice that people do this kind of thing but that's going
to lead us to the next point which is wiring this up with dependency injection because I kind of hinted at the fact that it's going to be used like a Singleton that's why it's doing that lazy andure created call but nothing enforces it to be a Singleton except how we Act it so I've registered it as a Singleton on our dependency injection container here and I also provide it with this social metrics DB file name so it's probably not how I would keep this especially because I probably don't plan to have a sqlite database for the lifetime of this but that's how I'm doing it for now okay so at this point what we've done is created a DB context and a DB context Factory specifically for our use case here which is going to be able to track metrics for us and when we
go to use this DB context Factory the first time it's going to guarantee that the database is created so that seems handy but we have to go use it now so where do we go use it well based on what we left off in the previous videos we have this fetching job and right now it's not technically fetching anything from the internet that part was commented out but let's jump back over to that job and see how we can use this now okay so in quartz I have this fetching job here and this is kind of nasty I'm really not a fan of this but how we pass parameters into these things is not through the Constructor we have to use this other context object that's passed in through the execute method and that means just like we did with the isocial data fetcher from
the previous videos we have this merged job data map and I'm just going to pass in the context Factory now because we've just created that so there's one more spot where we have to go actually pass this in I'm just going to jump over to that very quickly because it's right back in our program.cs file but we had this map that we were providing before and I've just added the line on 69 here that's going to pass in this new object for us so that's really the only spot we had to go alter to pass it in because I'm resolving it off of the container right here on line 58 so let's go back to the job itself we can see that we're now asking for it off of the merged job data map that's passed in from the context and we can still see
that right here where we're not technically fetching anything from the internet still commented out but I figured it would be kind of cool to see if we can go write some stuff to the database using our new context Factory so what I'm doing is creating a new metric and you'll notice right above I have a bunch of comments about some new questions that we have to ask I'll come back to this in just a moment because I want to wrap up the video with that part but once we create a sample metric what we can do is ask the context Factory to make a new context we're wrapping it with a using block here so that means once we're done and this goes out of scope it will close off which is what we want and then I'm asking for the social metrics table and
we're going to add that metric in and await it from there I'm just going to call the save changes async and await that as well so technically once this all runs we've got a new context added the metric in saved it to the database and then disposed of the context so we have all of the writing completed here from line 33 to 39 but that's going to bring us to this social metric part which is a little bit interesting based on where we've left off with our previous design and now that we have things like platform ID account ID the metric name and metric value the time stamp's pretty simple I'm just going to grab the current date time but these other properties that we're trying to provide here we don't really have a great way that we're getting that information based on our plug-in
design from before so that means that when we're looking at this thing here this fetching job is very generic and you can see that I have a social data fetcher commented out here but it's not like it's a Twitter data fetcher specifically or a LinkedIn data fetcher specifically and that means that to provide this information for the platform ID and account ID it's a little bit weird like I don't know where we're going to get that yet so some thoughts I had were that when we go to fetch that social stats object that we created if I jump over to it here you can see that we have a follower count and a following count those are the two metrics we talked about from before but if I go back to this job I mean maybe what we could do is add on the platform
an account ID so that anytime you're asking for that data you're going to get told where it's coming from like maybe that's a good way to do it I don't quite know yet maybe the social data fetcher itself could have properties on it that tell you that but so far I'm kind of feeling like that record that comes back might be useful but the other weird thing is that that social stats record has two integers one of them is nullable and one was for followers and one was for following if you check this part out I've now made the metric itself a string so I'm not using an enum here and if you watch my other videos on enums you'll probably know my opinion about things that I can't guarantee are constant I don't want to use an enum here because I already don't know
what I want so an enum's not a good fit in my opinion but perhaps the metric name as a string is going to be something that's extensible enough I'm not totally sure but also maybe we only ever deal with followers and following and maybe having a metric name and a metric value is separate things is just Overkill but right now I'm not sure it's going to mean that I need to have some way where we can map that data what that might mean is that when we ask the social data fetcher to get the stats maybe it is more than one record that comes back right so we would go ask Twitter for the followers and the following and if we go back to social stats over here this record the follower count and the follow Wing count this instead would be made up of
two different records right and the metric name we would put onto here and we'd populate it with the follower and the following count so my brain is kind of headed in that direction so I will probably end up blowing this apart and creating something new instead that basically looks a lot like the information that we have off of this social metric itself so the fact that this exists and this is what I want to write out to the database I am feeling like I probably want social metric or maybe not the exact same record but something that Maps very well to it coming off of fetch social stats async this API but I do think that I might want to have a collection of them come back because we're already seeing with something like Twitter that we would want followers and following and technically that's
going to end up being two of these so that's the direction I'm thinking of heading so that means at this point in time our Blazer application technically has a a plugin that will go fetch Twitter data we haven't seen it in action yet but the code is written we just need to have the credentials to do it and then we have the database writing part so we have these two opposite ends of the system and they're configured with a plug-in however we just saw what's not done right now is wiring up these two pieces right in the middle so how do we technically take the fetch data and remap it to the records that we want to write out I do think that we have a potential solution here which is just changing that fetch social stats API that we just looked at so I'm
thinking that's the direction I'll probably head in but I'm curious to see what you have to say like is that the next step that you'd like to see with this video series I think it would be pretty cool to prove that we can go start to fetch data and write it out kind of see it end to end but I'd love to hear from you about what you'd like to see next in this Blazer build Series so thanks so much for watching and I'll see you next time
Frequently Asked Questions
What is the main focus of this video in the Blazor build series?
In this video, I'm focusing on setting up Entity Framework Core for our Blazor app, which is designed for metrics tracking. I'm sharing my journey of learning Entity Framework Core while building this application.
Why did you choose SQLite for the database in this project?
I chose SQLite to keep things simple for getting started. It allows me to easily switch database technologies later on without having to rewrite the entire application.
What challenges do you anticipate with the design of the database and metrics tracking?
These FAQs were generated by AI from the video transcript.I'm concerned about the flexibility of the metric name and value in the database design. Keeping it generic might lead to inconsistencies, but I believe it offers the flexibility we need at this stage. As we add more plugins, we can refine this design further.
