Efficient data access & Effective object mapping with Dapper & .NET 5

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
i'm gonna go ahead and turn on the youtube stream should be going up that's that's the temporary one if you open up the participants list there's a raise hands button on there i think that one's the more permanent one so and i'm one of the officers we have a number of the other officers here on the channel uh eric sal uh russell uh durham and uh and justin williams i don't know if darren is online right now he may be on in a little bit uh that would be darren white so we've all been officers but we've been around the user group for quite some time actually scott dockendorff used to be one of the officers of this user group some time ago and uh so it's uh you know really great to have him back and uh have him have him speaking uh and uh so with that i will just hand it over to scott awesome thank you david sorry i'm getting all of that got some windows open awesome hello everybody uh thank you so much for taking time out of your evening to meet with us um i promise to deliver an efficient session and really the goal is just to demonstrate the kind of the awesomeness of a micro orm and dapper um i see some feeling familiar names it's good to see some some some folks for those that i haven't had the pleasure of meeting my name is scott dockendorf and i'm currently heading up technology for a company called remote operations [Music] so a little bit about me um i'll take two seconds for this so i'm a uh proud husband of two i'm sorry a proud husband and a father too wow that came out wrong um and um i love music i'm a drummer um i love live music so i listen to a wide range but i tend especially the live shows i go to i tend to be more like towards the rock and metal scene that's a picture of me myself and rob and mark from the filipino metal band death angel got to meet them back in 2019 you know pre-code um anyway so yeah as david mentioned i i was i've been a volunteer of user groups um i've had a strong passion for helping out with user groups um i started with dallas and then i had the opportunity to work with some folks here that are that are heading up this group and so as a program director for what four years here at with this group and currently the program director with the dallas group but again i'm just a i love giving back to the community and and however we can and it's just nice that we take the time and have the opportunity to attend sessions like this so again thanks for thanks for joining i've been developing for um over 25 years and i've been with dotnet since the 1a alpha so a little bit about the company which i hope sets the stage for why i was motivated to for this presentation um so i work for um a company called remote operations our platform is called doc fluent um we're a healthcare technology sas provider we partner with healthcare facilities um hospitals and and specific care facilities where our organization will take over the management of much of the tedious processes that that some of the practices have to deal with today so for those of you that are in health care you may know this and for those of you that aren't you'll be shocked at how much faxing is still a part of of healthcare today um but we'll take um medical records transcriptions facts management external reports records requests etc and we'll we'll manage those for our clients so in our ultimately we want our clients to if we can take that on for them they can focus on what's most important which is patient care we've been in business for 14 years and growing um because of this growth we um we're digging into some modernization efforts so we have we kind of have a wide range of technology um but and for us instead of having like a ginormous modernization project we've been able to tackle it in bits and pieces and we've been able to um dive in and address performance and adjust some things um with this growth really the motivation for this talk uh i'll take a step back so i've i've been lucky enough i've been i've used blazer uh i'm just a blazer i've used dapper for um really the past three past couple positions or past couple companies i work for i have i've used dapper in the past um but it wasn't until this one like in the last company we actually built a um we had a cyber security portal that we built which was largely lots of reads a little bit of writes so we actually ended up building our our infrastructure layer so that entity framework was what we used for writes and dapper is what we use for reads and and then i supported other applications that were built adapter in the past but what happened for us is as we've grown we had some back-end windows services that were taking longer and longer to run and by the time i started until you know fast forward a couple years from now we look back and some of these processes were taking anywhere from 24 to 32 hours to run to complete these long running processes and um so we dug in and we said you know what those are all using like a legacy com component for some of the data access that's still calling stored procedures behind the you know under the covers so let's go ahead let's just convert all those to dapper right so we can still use we're in.net they're windows services we can um we can we can leverage uh replace that legacy com component with dapper and we were able to reduce the run times from that we're at 24 to 32 hours down to 45 minutes to a little bit over an hour so the intention to say that is not to brag or you know try to pat myself on the back but it was like we couldn't believe that what a what a difference dapper made for our performance and what we learned was that this legacy com component and you know those old components were apartment threaded um didn't really leverage true uh multi-threading and they used um components where you had to traverse the object sets um the scripting dictionary where it would it was uh the hot the performance degradation was almost like a hockey stick on a graph where it was just it continued um to have poor performance um the more records you ran into it as you were traversing through each entry so dapper made a huge uh huge it was a huge win for us and so we've been able to leverage dapper in a wide range of um a wide range of projects we've been able to leverage it in ap windows services api layers that that fuel other websites and uh utility apps and other functionalities so anyway we we just it's been it's it's been an awesome uh the ability for us to to leverage um dapper to access data very quickly and map things to objects because we're all developers right we don't want to deal with data sets and data readers and all that we want to be you know working on the object level so it gives us a chance to do that so the goal for this session if you're new to orms or micro rms so i just want to introduce that concept try and put together an introduction for dapper where the code samples are going to be those common things you'll need to in order for you to use dapper i want to tackle things like querying getting multiple results um getting a single result um looking at um you know inserting and updating data and and how do you how do you manage transactions within dapper how do you get return values if i insert a record i need to get that identity back how can i do that so i want to be able to show some of those items and then lastly i've got a few thoughts on um when you know when does a micro rm help and um and some advanced topics that some have may have have run into with um transient errors and things like that so before we begin i just wanted to ask if everyone could um in zoom click on the participants window and you should there should be a button at the bottom for raised hands and i wanted to ask um excuse me man i got coughs um first how many people are using or have tried to use or spend some time in dapper if you can just raise your hand i'm curious okay cool how about any framework how many any how many entity framework folks do we have yeah some more okay great um and then how many folks are um so how many folks are actively working on net core or net five solutions okay good well the good news is for those that didn't raise their hand to that last question dapper can apps it can be leveraged in.net five dot net core or net framework applications you're not limited to net five from that perspective so um great thank you guys um okay so let's so i just want to take a few minutes i'm going to do there's a handful of slides to start we'll do a bunch of time and demos and i have a handful of slides after that so first i just want to start with data access so time and time again much of the applications that we write what are we doing we're getting data we're displaying data we're allowing you to edit that data we validate it and then we save it and then we you know kind of repeat the process so when it comes to data access within you know.net application um there's three common approaches to this technical challenge first i'm sure many of us have had to do this we can roll our own ado.net code so this is where you're working with the um the native objects in system.data.sql client or microsoft.data.sqlclient using sql server as an example um where um you're you're building this logic it's getting cold in here um where you're you're building logic with the raw.net now it's great because it allows you to get down to those lower level areas but um for many of you that for all of us if we want to work in objects and collections of objects you've got to build all that kind of plumbing for the manual mapping of the data sets or the data readers into the objects that you'd like to address so one modern technique is to implement an orm or an object relational object relational mapping tool so here you're living in native custom objects in c sharp um so there were there were about a third of you i think that raised your hands for using enemy frameworks so you're probably well familiar with this but with an orm your database is modeled to a series of object-generated code you can you can act you can um you can use sql but often you're not really spending a whole lot of time in sql rather you're relying on link or lambda or whatever is defined and access to your data now the orm system will have mapped your objects and your relationships in into that into that generated code so the objects have is dirty you know change tracking the data can be easily inserted or updated with persistence calls um database changes are handled by migrations which are c-sharp classes that allow you to adjust your database objects as necessary adding columns extending column um you know varchar column lists um adding an index etcetera for some individuals this works great this could be a you know it can be a fully functional implementation but to others it may sound like oh either you know i've heard oh man it's overkill like i've got i have an existing database i just want to run queries i just want to you know tackle and it just orms may feel like a big you know getting over that initial hump to implement it i'm not and i'll share with you in a minute i'm not saying it's bad i've used both and i've leveraged both and they both have done um they've helped us realize what the application was trying to implement all right what we're implementing with the application um but the kind of happy medium in between the two is a micro orm so um the team with dappers said they just wanted to target what they call the 95 percentile and that's is they want to be able to query data they want to be able to execute commands very quickly and then map the results to objects that's what they want to solve they don't want to solve their the intention isn't to solve all the other things that an orm provides for so that's where so i have a few examples of orms and micro orms under there and the two we'll talk about more today are kind of the two frequently used ones in the dot net space would be dapper nano framework so this chart we'll talk about this after the demo but essentially here's a little you know additional details provided but if you look at the column on the right excuse me um if you look at the column on the right that's the dapper again it's it it's it it wants to to have that object mapping with the the the plain old custom objects the the poco objects and run execute queries and commands um entity framework although offers you know has relationship tracking change tracking offers a second level cache designer and etc we'll come back to orm in a minute but for now let's talk a little bit about dapper so dapper is a microorgan um created by the stack overflow team so they and we've all used stack overflow right so we know there's a tremendous amount of data in their system in addition to caching they want an ability to have blistering fast data retrieval um and uh and then execution for for commands so um it is compatible with all adio.net providers so you're not limited to just sql server you can use other database types um it'll work with those as well um there are dot net framework dot net standard and net five targets for adapters you can again i so you can leverage them again if you're using if you have an existing uh or new dotnet framework application or anything with.net core or standard and it's an open source license so on dapper's website they talk about i pretty much mentioned this but their quote was essentially we're not trying to solve every problem we're trying to solve the 95 percent fake sad or not but the 95 scenario is reading and writing and object mapping so how dapper works essentially it's a new get package that you install and it's and it though it exists as extension methods that are off the dbconnection object so there's an example of a few i'll show you more while we're going through the demo but those extension methods allow you to perform perform the actions so dapper is using um in a perfect world the object the properties of your object the names of the properties of the objects match what's being returned in the result set if that's the case dapper will use you know the dynamic dynamic method generation to map your result set to your native uh list objects with your custom if you're again if your column names are the same score you'll be able to to leverage it if they're if they're different or you want to override those then there's another dapper um there's another nuget package uh available for dapper.fluentmap that allows you to adjust those field names in addition under the covers dapper is using a utilizing connection pooling um and then it also caches some query info so that it can hydrate those results into those objects pretty quickly some of the benefits uh to using dapper are simply performance um those um uh those that have leveraged it there's some articles out where people have compared any framework i've got a few stats i'll show but there's a um some have seen um that like the performance for raw8.net and dapper are pretty close but there are some scenarios where dapper has shined over ef core and then some that it's better but it's not tremendously good i've got one example of each of those um but dapper allows you to uh it'll it'll help reduce the amount of code you can virtually get rid of the code you need for um for mapping to objects and then your query command execution you'll see in the demos it's much shorter than probably what you're used to um dapper does allow you to leverage the the benefits of sql and so if you have especially if you have an existing database and that database may have lots of you know the dbas may have put together some abstraction layers so that they can control performance so they may have lots of stored procedures or there's business logic in there that you need to account for it's it's pretty straightforward to implement that within dapper and then for us again i'll talk about it in a minute but there are there are some some believe that orm play a certain role in microarms play a certain role i don't know if i subscribe to that theory i believe that if if it can meet your objectives and um and if your application be the enabler for some business feature if you can make it work then make it work i think it could work well um here's an example i referenced these articles that i found but um there's a couple of them it's worthy to look into if you're interested um they talk a little bit about especially if you're interested in ef core and turning on tracking and not using tracking but in this scenario it's a thousand records which is really a absolute blip probably for some of the databases that we have all had to have to use and support and manage but in this example for what they had put together dapper now those times were all in milliseconds but dapper was the clear winner by far from each of those entries there was another example where um dapper won and all three uh all different types of requests um but it was not as much as the last performance i think a lot of those it all depends on you know the the types of actions you're attempting the data that you're trying to reach and there's always factors with databases are they index are there too many index where inserts are slow but but the retrieval is faster so there's always so many factors that comes into it but how do you get dapper i'll show you here in a minute with the demo um it's pretty easy you simply add dapper a new get package and for netcore.net five you'll eventually add a dependency to microsoft.sql client um and that's it so at that point then you're really living in the c-sharp world so let's go ahead and jump in in the demo okay let me launch this virtual machine so uh i put in a ref oh while i'm i i want to jump in have there been any questions so far nope okay good i haven't seen any awesome so if you find the demo interesting and you go i'll provide a link to the github repo um first i wanted to just share uh in the solution there's the there's a sample the the c-sharp sample um there's the the pdf of the slides and then most importantly i had a database script so if you look at here let me try this yeah okay so here um i simply found i wanted to get some kind of um like a production database so the the fine folks over at sql server tutorial.net have a sample database called bike stores so included if you're interested in that project included in that are scripts to you can create all the obj once you once you create a bike stores database you can create you can drop all the objects if you want to start over create objects load data et cetera so i'm only using a portion of this for the demo um but it's there in case you want to you want to kind of fully feature database that you can jump around in so here i'll show you here so um what i have is i have sql server running locally um i have this the the bike storage database in the database there's two schemas um the way they've structured the data is um there's two schemas one is production and sales so production this is a a bike like a retail organization and this has a back-end system that probably runs at corporate because there's um there's the production tables which are really look ups like what are the brands that we sell what are the categories and what are the products that we sell um the sales um sales has customers and the tables we're going to be looking at are orders and order items which is a pretty straightforward concept and then the we'll do some updates to the brand table but if we take a look again we have the sales orders i'll do sales order items so it's for many of you that have worked on retail or or e-commerce type applications this is similar to probably what you've seen before every order that's placed has a has a primary key which is an order id we've got an um a foreign key reference to the customer there's an order status there's a series of dates for order date required date ship date um here we have what store what brick and mortar store the purchase the order was placed at and then staff id is the um is the sales associate that they place the the order with um and then order items or what you can imagine that's there's the the reference to the order id and then here's the primary key for the item itself um what product did they order how many how many uh how many of each product did they order what was the list price and the discount so this this table actually doesn't have a the actual line item cost and so i'll show you we'll derive that with a computed column but anyway so pretty straightforward database probably something similar um so let's go ahead and start what i wanted to do we'll start with a clean project i did i do have some items because i didn't want you to see me fumble over some of the typing there's we're going to do of course some of the demos live there's some that i'll just i'll copy over from a snippet we're going to create a new project and i'm going to go ahead and create a net core console app and i want to put this in all right i'm going to put it in a new folder called north dallas i'm going to call this demo i don't know about you i'm still it kind of drives me crazy that in in visual studio 2019 you have to you create the project and then for some reason when it creates it if i go to the project properties by default it's creating it it's targeting.net core so dot net core 3.1 and so i want to be able to do it to five let me go ahead and clean the solution and rebuild okay let me get my snippets in play real quick so give me one second here okay so now we'll go ahead and load the project there we go it takes a minute for those those demo snippets to come up okay great so first thing i want to do i want to i want to let me get a few plumbing items in place so first i'm just going to create it's just supporting methods to do logins which is just nothing more than console.writelines and this first and this is an example of like please don't do this and how you have your production codes so um please don't keep your connection strings in plain text please don't uh in place them in source code um but i wanted again i didn't want to have to spend time doing all the plumbing so for this purpose we're i'm just going to leverage this uh connection string here but please encrypt it and try to keep it out of the application somewhere else right in app config and kms and in um key vault in another area but um but for this i really want you to just focus on the the dapper piece so okay so we've got we've got a connection string we have an application um first thing i want to do i want to make this little checklist that we're going to use so what i want to what i plan to talk you through and we'll go through each one of these but i want to show you again common functions you'll need to start using dapper today or tomorrow in case you haven't started using it before so we'll talk about queries so we'll start with queries we'll talk about calling queries via text or stored procedure we'll talk about getting multiple results we're getting to talk about a single result we'll talk about um you know some common solutions around trying to are one way to get a parent and its child data um with regards to order and order items then we're going to spend some time in updating so we'll have some quick methods that will show you how to update whether it's a texan with a sprocket i want to introduce transaction management within dapper we'll talk a little bit about return values and um and then a nice little utility that allows you to perform insert you can insert multiple objects within a single command um and then we'll lastly talk a little bit about exception handling and then um i did want to present one approach that i started using at the last company um just a way to structure your queries and commands that i thought was kind of a neat little design trick so i just want to share that with you so um first thing i wanted to do is we're going to focus on querying the order table and the order items table so um what i what i'm going to do now to get ready for that i'm going to go ahead and create create a models folder and then here i'm going to go ahead and add a class free order for the order table just so here we have the order table um what i've done is i've taken let me flip over to sql so i took i created a class with the same fields that we're going to return back from our query so here we have order id customer id order status order id customer id order status etc so i went down the field so these integers we've got some the date time fields and so here's the data we're going to turn back for the order let me go ahead and i'm going to add another class for order item under models and then okay so here's the order item um and so here are the fields that are on the order item table and i mentioned earlier that the table doesn't have a line item price of what i i just built a derived column where we're going to calculate that based on the object values okay so first what i'd like to do is i would like to show um i want to show let's take a look at what what it means to query to get a list of orders um using ado.net all right so i'll go ahead and then for here now this okay so now that i have the classes in place um so and this is adio.net code that you have most likely um seen or written in the past now let me fix some of these compilation errors uh let me insert the using for the collections object oh what going to do so if we're going to use adi.net uh let me manage nuget packages for solution and go microsoft dot data dot sql client i'll go ahead and select it'll add a whole slew of assemblies okay so now that i've added that let me we do the using statements for sql connection okay so here we're going to list all the orders um the result is going to be a collection a list of the order object um and here you have the query select you know top 10 from asterisk from sales orders you got your um you you use the using statement for the sql connection you open the connection you build your command you define the command type the command timeout and in this case we're going to open a reader we're going to execute that statement and get the reader and then while we read and it's going to read every record in that result set perform some kind of mapping into that custom object add the results and then at the very end it's going to take that result and it'll print out the the result so pretty straightforward um yeah go ahead and run this so it queries the database and it found the first ten orders in the system and there's order id one two three four i to ten and then the various dates the order was placed and shipped so pretty straightforward right now let's go ahead so i'll comment that out now let's take a look at what it means to do this in dapper so so load orders dapper via text oops let me generate that method okay so now for dapper if i go to nuget and i just search for dapper and here uh take a look there's lots of other dapper libraries where people have looked to extend the reach and the capabilities within dapper but right now we're just going to focus on the first one um it's at least 69.6 million downloads so i select that and go ahead and install it okay it is installed we close these okay so now let me show you what it's like let's see show you the difference between the raw kind of ado.net so i'll just do this so let's take that ado.net code and i can show you how this changes so um here we can see we've got the same my result in fact you don't even have to do you don't even have to new it up we can just call this and say my result you can have the query definition here um select top down from sales orders you can still have the same using command but in dapper you don't need to outside of using transactions you don't need to distinctively or you don't have to open the command you can do that by default um you can you can reduce this down to so you have my result which is the variable we defined up here is we go to that connection so here is where the the extension methods are so when i go to con i get a query oh hold on using dapper okay and actually let me put in using dapper models okay or adapter demo okay so i have the using uh statement for dapper so now uh yeah so now if i go to connection dot now you see all the series of extension methods that dapper adds in so there's i'm going to do a lot of synchronous examples query um query multiple et cetera there's asynchronous ones that can fit that can help help you as well if you want to build this asynchronously but you'll see there's a series of queries there's also there's execute and there's some other overloads as well so we're going to go ahead and take we're going to use query now you want to pass it a type of what you're expecting so in this example we're trying we're expecting order the order object parentheses parentheses and then we're going to return a list so i'm going to convert it to list with two lists and then in the inside now you can pass in the property so i can go sql and i can pass it in query command timeout 90 command type oops so command type dot in this case we're going to do tech nope my bad text and that's it so so with that i can delete these entries and most importantly all that goes away and that goes away as well so um what now i was just able to add the using link clause up top so now i was able to convert that query down to and literally those handful of lines of code so let me run this i'll do dapper save it and when i run this you'll see it just ran through the same one so um it was it's just so much time i i don't know if many of you if you've built your infrastructure layer or your data layers where you're having to do like using rawadio.net man you're constantly having to write that mapping code it's just after a while it just it's plumbing and it's tedious and wishing i had codesmith or something that will allow me to generate stuff right well dapper by its mapping allows for that so it's kind of nice um okay so that's a good example of how to get use dapper um for loading multiple records uh let's see what else we have um now let's do that same query but within a stored procedure so i'll do load borders via dapper sprock so calling a stored procedure is not that different from actually calling it within i'll copy this so if i go out to the database and i look in programmability um let's see so good most recent orders let me see if this is it yeah this is it so i can take this to our procedure name i literally change that to the stored procedure name and then i change this to start procedure and run it and you'll get the same result so it actually will map um the values from the stored procedure so just with a q a a few small tweaks we'll get you um we'll provide you the ability to execute with a stored procedure okay so that's an ex that's a good example of being able to load um load the orders via a um to get multiple results but now there's sometimes when you want to get one results you want to get the object itself so let's take a look at that so now if you want to get single load order via text i'm going to pass in a 1 and that's going to represent the order id that i want to return so generated that method so here copy this code okay so we want to get a single order back from the system so i mean i'll change the the um definition to order id okay i'm going to load order via text so what we're going to return is not a list of orders it's going to be a specific order i'll call that my result so i remove the list definition from it from the query um we'll go ahead and use this so select asterisk from orders where order id equals order id so what i would like to share is another one of those please don't do it the way we're looking at it here i would ask you please please please please don't be tempted to do this right so there are some that that um that use string concatenation to build sql and i can't stress enough like please please please don't do that because you imagine if this if this variable was if the input variable or you know or string it just totally opens you up to or it's susceptible to sql injection so oh i lost my spot sorry hold on so not to get all on a security tangent but this is where if for some reason you're passing in a variable it's too easy for someone to make you know order id equal to um order id equals zero or one equal one semicolon drop database bike stores and if you happen to be connecting to your database with sa or some other admin account you're in a world of hurt so um so what i would again recommending for strings just um one way that you can protect yourself is through using parameterized queries so in dapper you can do that with with an object that adapter object called dynamic parameters so sorry let me do this okay i'm going to get rid of okay so i have the query select ask from sales dot orders where order id equals the parameter order id so for dapper you create var qp equal to new dynamic um i have using dapper up top all right so there's dynamic parameters and here you you know qp dot add and then here this is again probably very similar to to how you you may have built uh parameters in the past um but here we're going to a parameter has a name it has a db type of dbtype.int 32 [Music] you can define a parameters direction so direction can be an input parameter an output parameter input output parameter or return value we'll look at return value in a minute so this is an input parameter and here i'm going to do the value i'm going to pass in the value that's order id which is the variable defined in line 49 above okay so now i must have commented that out um okay so uh now we we keep our same using connection um so we're returning one record back so we're not we don't need the two list because we're not returning a single list and for here we're going to call the query first or default method and we're accepting an order object or we're expecting an order object to be returned as a result of this query now the difference is now you just pass in parameter or param colonqp comma and that's it and then so for here i can just return so that logit message is just going to say order um since i'm i'm getting i remove the looping through each one since we don't have a collection so it's this is just going to say order one was placed at whatever date and shipped on whatever date okay but essentially to to change it from returning a multiple records to a single result again i just changed the query to query first or default removed the to list and then the type is the it's just returning the order object so if i run this oh that's what it was okay i thought i did something and that's why i'm copying over some things you have to watch me code or watch me type oh and i changed this to text i had a distorted procedure there you go so then it shows that order one was placed on this date and that date so um i hope you're seeing that the like it's it's a trivial amount of code to be able to run some queries it's kind of nice to not have to deal with that mapping logic all the time but okay so let's see the next uh next thing i wanted to show you is um there are some any framework one of one of the advantages or true or m is that it can handle um it handles relationships between tables really well um but um and another one of those kind of database stipulations that we always try to recommend for performance try not to do select star from these tables because you're returning especially returning a ton of records you're returning a whole bunch of fields if you only need a couple fields from that don't don't bring everything over just bring you just do a partial write write your query to return only those fields that you need and go ahead and result so i wanted to show two things with this so first is um let's say you have a um well so there's a sprock we i have a sprocket here which is get order summary so in this case it it's returning the order field plus it's returning the name the full name of the customer and the sales associate so i i did this for a purpose i want to show you this so what i'll go ahead and do there's there's a customer name a store name and a sales associates there are three additional fields so let me go ahead and create i'll take this order um so i'm going to make a duplicate copy of this order i'm going to call it order summary right so i go here to order summary um and then i want to do i want to add i'm going to add three different properties to it there's store name there's customer full name the other one was sales associate full name okay and so in this example um the sprock is sales order summary so let's try this uh here i'm going to do load summary vs rock um so let me create this okay let me just say that's proc name so now i'm going to go ahead and change this so i'll take this i'll now i'm going to take the stored procedure name and i'm going to define that as the query it has a parameter called order id and i'm passing it in okay okay so it's going to return instead of an order object it's going to return the order summary object right so it calls get order summary it passes in an order id and so i'll change this to stored procedure um and it's yelling because it has the different discrepancy from the order object so here we're just uh we're going to run the same query first your default calling this to our procedure um and let's say i want to change this to let's say we want a message called um oh it's a good example order my result order id um was placed by i'll call it um it was placed by um order id from store name i and i'll do my result dot sales associate no customer first name no that's right sales for this customer anyway i just wanted to show you an example of returning fields back um so we'll go ahead and run this and here it says order one from santa cruz bikes by mary copeland for jonathan velasquez where jonathan is a customer okay um one of the now this doesn't really fall into good database performance issues but i mentioned earlier like um have a query that only returns the fields you need one of the things about dapper is that for example as you noticed i didn't need the only fields i used for the summary object was order id store name customer name full name and sales associate so you can build a class that only has a handful of the properties from the query so if i run it it's not going to fail it found objects that that um oh sorry and it runs and so uh the fact that i had an object that only had some of the fields i that i that this class cares about that's totally fine it'll still run so a a a database purist or performance purist would tell you you know what just write a separate query that only returns those fields you need because in this example it's only returning one record but imagine if it was returning tens or hundreds of thousands that's a bunch of data being marshaled over the wire that you don't need for that particular purpose so anyway but i just wanted to demonstrate the fact that in dapper you don't have the objects your your objects that you map into don't have to have every single field if you're only looking for a partial you can do that as well okay all right so i'll go back to the program so another way this isn't as elegant as um this what i'm about to show you is not as elegant of a solution as like any framework as some of the others but a lot of times you're dealing with a parent you know a parent entity that has child entities of basic in this case we're talking order and order items so there is one approach to this and i can uh i'll show you this uh let's see here this is one that i've i'll walk you through this one so get we're gonna we call this get order and line items and i'm passing in the one again for the order id so there we go okay so in this example um dapper allows you to run queries or store procedures that will execute and return multiple result sets and how it does that is there is an extension method called query multiple so in this example um you're returning ultimately it's going to return an order object but also order line items object oh yeah let me do that so if i go to the order object let me uncomment that out so now the my my custom order object has a a list of order item collection called order items okay so now that it's i've enabled that in the object now let's take a look so the query itself what you see here is there's two queries stacked on top of each other one will bring you the will return the one order and the next will return you the multiple order items so here we have a dynamic parameter where we're passing in the order id where this information is defined same using clause you've seen before um same type of call the difference here is we're doing we're issuing a query multiple not just the query and what happens is from that result you can cast it as follows so you assign your object order equals in this example the multi which is the result multi.read and you give it the type of the of what object type that you're expecting back for that in this case we know we're going to get one back single so we use single for order items here where we issue the same multi i'm expecting an order item back and then here i call the two list on it so by doing that and i can set a breakpoint so we can take a look at this i'll go ahead and run it oh so here we are at the break point and i'll go ahead and take a look at the order and so now we have our our order one we've been looking at for all for this parts of the demo and here are the order items in this case we have uh three order items and i thought there were five that's why i'm pausing for a second but anyway i'll come back to that uh so yep now we have an object that has our order and then we have order items we have this information here and each of those are that retrieve the values from the table so now what i did in the method after i after i obtained that information i'm now using um i'm i'm summing up the values of the line item price and if you remember line item price is that derived column which took the the list price and subtracted the discount to get the line item price so this is what so all i'm doing in this method here is i'm summing up those amounts and i'm just going to display this amount here at the end so let me hit f5 and oops i need to format but order one has three line items at a total cost of 4 563 okay so need to format that but anyway so that's one way to get your kind of parent and child relationships not the best but it's a way that you could consider another option would be if you had a separate query for that you could within the same using statement be able to query to get your object and then whatever what your parent object and whatever child objects you would need you can call those as well okay great we've talked so much about um querying that that kind of i believe covers the majority of the query type examples you'll have how we do it on time so pretty good okay so now i want to spend a few minutes and talk a little bit about updating what does that look like performing inserts and updates and and and i want to bring up a few uh concepts of transactions and looking at return values etc so what we're going to do from the database perspective it's just something really simple um there is a table in the production environment called brands here how long we do this so select asterisk from production.brands okay so this is essentially a lookup table right these are the brands of bicycles that we um that this this this retail location sells so what i'd like to do is go through some examples here um since we're going to be dealing with brands i'll go ahead and create a class brand.cs and here i'll create int for brand id string brand name let me make sure that's what it's called yeah brand name okay so i have my entity class um now if i go back to the program so now for update with text um i'm going to call this uh first we're going to um i'm just for the demo i'm going to wire up b or var b equals new brand and for this we're going to say for what we're going to do is that for heller has now been acquired so brand id is going to be equal to 3 comma brand name is equal to metallica so metallica has acquired and want to create metallica bikes so they now that's their brand name and so what we're going to do is we're going to go ahead and update um brand via text and we're going to pass in that b okay all right so we're going to call that that calls it something a little bit different okay so we're going to update the brand with text and we're passing in that that b object so this simply is going to perform an update statement set brand name equal to metallica where brand id equals to three okay so let me walk you through this and it's pretty straightforward again a lot of this should look very similar to what you've just seen um i'll talk about result in a minute but here's the query uh we're gonna we're having a we're gonna perform a uh a text-based query we define the dynamic parameters that are that are included within the query you have your same using statement we've been using uh that we've included now this is a little different so instead of query or query multiple um you're executing an extension method called execute and that execute you can still um i just happen to have the parameters in the same location but you can call like we did before but you pass in the query next you pass in the the the query parameters next in this signature is a transaction i'll show you that in a minute next is the command timeout so if we want to keep this at you know 60 seconds or whatever we can do that and you pass in the command type right so that one execute statement this will perform the update what it will return is the result of how many records were affected by this uh by this command so that's true as long as like if you have a stored procedure where set no count is turned on um that will not it won't return the actual number of records affected by so you'll have to look and i'll show you about a return return result there's a different way you can find out whether that was successful or not but in this example it's going to return with a result of one because it updated one record because it matched within that query okay so i'll go ahead and run this and brand updated with the result of one again one is for one record that it updated and now if i query the table you'll see that record three was changed to metallica okay now next next we're going to do the same query but and let's say metallica got acquired by the great iron maiden so iron maiden is going to start selling his bikes yes i am a metal head at heart um okay so the next thing we're going to do i want to introduce transactions so i'm going to call this method update brand name with texts oh with text with transactions and trx okay so transactions uh i'm i'm it's probably safe to assume many of you who've been working with databases have run into this before you want to um you're maybe doing a whole bunch of things and if something fail right you're taking a bunch of actions on traversing through result sets or etc and if one thing fails you don't want the rest to go into the database great way to handle that is through a database transaction if you're doing seven steps and what something fails in the middle you want to revert that make sure those changes are not committed to the database interrogate go figure out what's going on and try to fix the issue so a good way to do that and so um transactions are fully supported within within dapper so now let's take a look at this so with texts and trx okay so a couple nuances with dapper and transactions so first and foremost you have to [Music] ensure if you can't start a transaction unless the connection is open so there are times you may have to explicitly be open right you have to you may have to call database open to be explicit technically you probably should do if right db dot that state is equal to or actually if not db state is oops oh what is it what i'm trying to think of that command um oh my gosh why have i forgotten this dbstate is equal to sql connection dot is it i forgot there's a way you can measure the state on the connection if it's closed go ahead and open it um but for that for the purpose of this we're going to go ahead and open a transaction i'm sorry and open a database connection and now you do um var trx equal to db dot begin transaction so now you have a reference to that transaction um and if you remember i ran the query and the third parameter in this query oops was the actual trends of the idb transactions so you passed in trx here where i executed it right so now um we can execute this transaction and then you can check to see oh wait we do inside then you say if for example result is greater than one no greater than zero then we know is successful uh go ahead and trx dot commit transaction else trx dot abort um roll back it's not important so you can roll that roll back a transaction right so then db dot close and then you close your connection so scott we have a question uh would dapper support transaction scope yes and i found out the hard way actually uh yesterday um i i ran into a scenario where i was trying to i was performing a function i'm calling lots of stored procedures right so i was like six calls and it does support transaction scope but if for example one of your short like i ran into one of the stored procedures that like the fifth of the six i was trying to call actually does a commit then it'll throw an exception because if one of your sprocks already has a commit transaction it'll get committed there and then once you go back and then try to issue a commit it's going to fail and say like whoa the the transaction count has changed from what i thought it was before you entered this call into now so that's something to keep you have to keep in mind like you'll have to under like in this example like for what i would want to do i'd have to then make a copy of that sprock that didn't use the the the the commit and the rollback so that i could do it all here within this entry but if you commit it midway through you're going to run into an issue i hope that answers the question so if i look at um so one of the things i want to do just to show transactions of work of just for grants i'm going to go trx dot roll back i'm going to go ahead even if it's successful i'll roll back the transaction and you can imagine what's going to happen is that iron maiden will not get written to the table and it will stay as metallica okay so i'll go ahead and make sure this is yeah run this and so it says it was updated with the result but that's just static text and now if i look at the query and i run the same query again record three still stayed at metallica because we rolled back the transaction so conversely if i change it go ahead and do issue a commit if it works f5 and if i go back to the database now threes aren't maybe so just to show you transactions really do work so it's kind of nice when you have to when you're able to perform those additional functions so okay let's see so if i mentioned earlier let's change this to anthrax okay so anthrax acquires uh iron maiden yeah imagine that okay so now the next demo or the next thing i wanted to show was introduce the concept of return values so um for here let's see minimize this minimized okay i wanted to introduce this concept of return values uh so i'll go ahead and pass this in so here we're gonna we will call a sprock here i'm gonna pass in b okay so um again i mentioned that the the whole idea is it a return value from an from an execute statement typically has the number of records that were um that were updated in the query but if that query if that stored procedure has set now no count on then it will not return that so you need another way to kind of know whether you're whether your command was successful let's go and take a look real quick at this store procedure which is production update brands so let me go production update brands so in here here's an example of um so here's an example of this stored procedure has the set note count on and it has and here we're returning where it performs an update statement and this this runs for sql server it's running the at error symbol and that will give you in the context of this query if there were any errors it'll if everything was successful it'll return a zero if if there were any errors commands it'll return something other than a zero so from the code perspective what you'll see that's different in this scenario is line 71 here that shows that there is a new value and it's not ironically it's not defined at error um it's just a kind of a reserve name for the ret val it's going to be the the parameter direction of return value right so that's a little bit different so it's an integer it's a return value um and then we're passing it into the query as we expected um and what you do is after the execution you can assign the variable by saying query parameters.get cast of type integer and what i want you to return is the uh the the the variable ret val which i defined up here as being the return value and now i can check that my my return value if it's equal to zero uh if it performed the update then great it does the commit else the rollback so i'll just i'll set a break point here so we can take a look so here you've got the database connection object opening beginning a transaction i perform the execute so once it's done my return value is set to zero so i know that was successful so i'm here i'm gonna go ahead and commit the change i'm gonna close the transaction and then i get out and now if i go query the database the third entry is now changed to anthrax so again just to show um it's a different way to get return values um i know through dbas i've learned that setting no count on supposedly increases performance um that's what i kind of believe to be the case i think others could probably verify that or call me on in case that's not the case but um i believe it is at least that's what i've learned uh in the past so maybe that's changed over different sql server versions but anyway so that's another way to get um to obtain um some kind of notice if your execution was successful or not okay let's see insert let me take a look at this okay this is one kind of cool thing about um i'm gonna do this okay one another another neat thing about um dapper is it allows you to well you start with one statement in this case there is this is um we're executing we're inserting into production brands band name i'm sorry brand name and values of a now that a can be a a collection so in this example let's say i would put let's try um you too excuse me you too um now let's see what else i want to do um and then if you uh let's see what i want to do what else you want to do um yeah sorry so you can uh what it'll do sorry is that you can execute dapper will essentially translate this so if it finds the multiple values passed in in as the string array it will um translate it to multiple sql statements and it'll execute it as such so what appears to be in this account we're saying hey go ahead and execute run this insert statement um and then if you pass in a string array it'll translate to multiple insertions and then it'll um and then it'll execute those so um that's one example i did what we're doing on time all right i did want to show you [Music] come back to this um i wanted to simulate in this example i want to simulate an error so all right let me do this aaron exception handling the nice thing about dapper is you're dealing in the world of you're in c-sharp right so you're you have your common debugging mechanisms you can build integrated integration tests around if you need to um but you're in the land of c-sharps you can debug and you can perform those items um hold on and i had an extension method that would actually would pull out the inner exception error um but i want to focus on this so in this example we have this this method so list data but error in this example i'm going to i'm trying to force an exception um by dividing uh one by zero and so that that that'll trigger an error and i just wanted to show that um the nice thing about that but you're in the world you're you're normally in um in the sense that you can you can handle uh you can put try catches and handle certain exceptions and uh manage those appropriately so for example um you know there's one where again i'm gonna force this error we can go ahead and i can set a breakpoint go ahead and run it now if i go so i'm going to try to perform the query and you'll notice that it kicked out with a sql exception and that exception was a divide by zero encounter so again you can you can wrap your try catches you can manage all that um if you are explicitly opening your connections make sure to do it finally outside the catch and close it make sure your you know connections are closed if you need to etc so that's one exception i think another one we could we could follow through to show you the error another one would be let me try to do this i'll just do i'll just adjust the database name so the database doesn't exist and it can't open it so now if we try to do this okay it should come back with another error i was hoping that it would trigger oh so it's still yeah that's right it would be a sql exception because because can open database requested by the login the login failed for the user so anyway so it's good you can rapper again you can rapper you can sub type subclass your exceptions and be able to handle them accordingly so it's a again it's a familiar space when it comes to like you know c-sharp development um okay and then last thing i wanted to show this is more of a preference um i started getting digging into um i found an example of jimmy bogart's where he redeveloped the microsoft's contoso application the way he would want to build it so um i have a link for it it's actually a hidden slide but one of the things i started getting into is feature slices and looking at mvc and apis and what i i started grouping all the models together and all the commands and all these things and what i've found and any of you that may have done that in a project some of the challenges are you're just looking oh let me go get the request and then here's the response and you're you're kind of searching all over for code and what i found is i started gravitating towards grouping the like projects together and keeping them you have feature slices and another way um and this is more of a design aspect but i wanted to show show an example so um so i'm going to add a folder imagine you have an infrastructure library you have queries for example so i'm going to create a query i'll just call it um get orders right so i just want to show you and this is something where i've it's kind of the next step of like okay i get that like i get i understand how to use it how can i kind of structure this and so what this is is um it's a class called get order um in this example um you can either you know use dependency injection or i'm passing in a connection string or that there may be better ways for you to handle that in your application but the idea is you you the this actual class represents everything that's needed to run this query so it contains your request so here are the values that i i need to send to the query it's a sub class within get the get order query so here's my request this is the data that i need to provide you here's a response and so the response has some properties that you would like to return in an api call for example was this query successful like did it did it process to completion successfully does it have a value um and if not what was the error message and then here's the the data what you're returning back in this case is an order object right and so then the class has a a method just called execute and there's a request that we pass in the request and then here's the response and then the dapper code it's really similar code that you've seen through most of this demo right for the using query first or default and the difference is i'm just populating basic fields within that response object and returning it back so um again it's more of an actual sugar or like a design approach but but one of the things i've i've started gravitating to more queries like this because i love that it's all in one class and it uses a subclass and there's no question of what or requests or responses are needed so so just more of a design aspect here so um any questions before we continue no but uh parks thinks that project design is a great topic cool i think well so and that's right i want to highlight this a little bit i do think there's a there's a okay cool i get dapper like i understand it's pretty straightforward like how do i take that the next step and that actually is a talk i would love to give it another time which is where we could and i'll talk about it there's some additional topics um um there's some additional topics uh which like kind of designing your data and infrastructure layer i don't know how many of you have spent time with like steve smith uh is is promoting clean architecture you may be using your own kind of there's onion architecture there's clean architecture and and where that factors into design is it's it's kind of fun again my last project which was a total greenfield project for us we were able to use again entity framework in the repository pattern was able to use uh um a unit of work um and then it just it messed really well uh enemy framework was a great at the time was a great solution for us for that but dapper was fantastic for us for reads because it was so fast um whereas our current environment again we have we have some databases that have been around a while and they're sizable and there's lots of the back end um in the back end so um ef would have been a little bit more challenging for us it could be done i'm not saying it couldn't but it would be a lot more challenging so dapper just fit in nicely and it's really kind of paid off wonders for us so um so this is i'm sure many of you share these opinions um for some ef versus dapper orm versus microrm is a pretty passionate belief um and i'm i'm not there i'm not gonna bash ef i don't i can tell you i enjoy working with dapper more i feel like i can get to where i want to be quicker than i can by setting up bf but that's not a knock on that because i think um in my opinion i think they're both very functional data access and object mapping techniques again this is the world according to scott view and the more you if you're interested and you start researching this topic more if there are any fan if there are any people here who listen to the sports radio the ticket i'll use the phrase hot sports opinions there's a lot of hot sports opinions about orm versus microorgan some believe that oh orms are good for micro orms are good for just like utility application but orm is the way to go um i don't subscribe to that theory um i think they both work well but i think there's two things you need to look at of course you need any technical platform you choose or any technical component you choose you want to make sure that it aligns with the functional requirements it brings the functional requirements to life and you can honor the commitment you are making on the application you know to the end users making sure it makes those kind of dreams a reality but i do believe it's totally an environmental fit um if folks can take a second and jump back over to the participants i wanted to ask a question how many of you have worked in a you know mid-size to large application for a team or company that has a dba team i'm curious how many people okay so about about a quarter a fourth of it so hopefully this will resonate then um so i think again i believe you know i've always said like every ita environment is a unicorn right so but there are some similarities right for for smaller organizations you may be on this call you may be the sole person um responsible for building this application right you may be from design inception uh development testing implementation and support you've got it all um and if you're a full-timer with that organization then great then as long as you feel like you can continue to support it i i think it's awesome you can pick what whichever whether it's any framework dapper or what other technology um but for smaller organizations typically some of the not always but some of the projects are new projects or you're dealing with a greenfield kind of application where you can build everything from scratch so if you or your team members are well versed in c sharp um and feel that you can um take on the responsibilities of you know an orm then then have at it i think you know you'll be successful mid so for the five or six folks that raise their hand and i i can raise mine i was one of those where i've worked in an environment um that i wanted to ask how many people of those people that raised their hands how many people had to submit interface contracts to dbas that said here's the query i want because there are sometimes there's the partnerships with dbas can be very strong and there's some that can be a little bit adversarial where they're oh we'll be we'll build you the store procedures you just tell me what you need and i'll give you the sprocks and and i'll build it because they like that layer layer of abstraction right they like the fact that they have more control over um fine-tuning performance so it doesn't require an application change it's a very passionate topic but i think some environments um there's a great partnership um i've worked in some i've worked in some where it was a little bit adversarial so you had to find that happy medium that works between the teams but databases can exist they can exist for a while they um they've built and grown and organically grown over time yeah the database may consistently or inconsistently have some business logic that you have to account for in your application um some may have a lots of joins there's complex queries to get to the data you need may take lots and lots of joins and that is where i still have i still have much to learn on any framework when it comes to fine-tuning queries i personally had problems with entities entity framework when it came to some of these complex joins and understanding what happens under the covers we had these pages and views that were taking a while to load and so i'd load up sql profiler right and we would we would we'd have secret profile we'd run we'd watch and see what um what's happening you know show me all the queries that are taking longer than you know 10 seconds to learn and none of them would show up but then we looked and it was like 100 queries we wouldn't execute under the covers and so it was um like i said i'm not an entity framework expert and i felt like there was a lot to learn as far as a fine-tuning perspective um but along those lines tim corey wrote an article about enemy framework versus dapper and what he recommends um my big takeaway from this article that's referenced is wasn't really so much the the feelings of where it's good and bad but like the idea that we as as developers architects um development leads etc we need to look at whatever technology you choose you have to look at the team and how the team can embrace a different technology so i can answer these from the dapper perspective right so when you're considering your approach to using dapper does your team understand how to use dapper well i hope the demos have showed it's pretty straightforward to implement within dapper um there's low barriers to use and there's not a whole lot that you need to kind of get started does your team know how to diagnose issues with dapper code well i hope the demo showed that you you can debug f5 debug um and you can there's no generated code so you can debug with your sql techniques or with your your common.net techniques do you know how to diagnose underperforming dapper queries to fix them well your dapper queries are your sql queries so um hopefully if you wrote them great you can you can fine-tune those if not you can work with someone on the team or somebody on the database team to help out if you need to does your team understand the code that dapper wrote for you well enough to know what it's doing well the good news is dapper doesn't have any generated code so um of course you'll need to do you probably research and see if you're fine-tuning performance you may have to get a little bit deeper under the covers but i've like we've yet to do it and we've been rolling out that for quite a bit in our organization so um there may be a chance there but for the most part dapper doesn't doesn't generate any code for you so there's nothing that doesn't really apply and then lastly do you know how to protect dapper credentials on client machines well this is no different from ado.net dapper orm or ef um you know the recommendations right or encrypted please don't store that information in source code but put it in somewhere else whether it's amazon kms right azure key vault uh cloud configuration within your web app server variables or someone just outside of the application but that's no different from any other technology there's nothing really specific about that um we're doing pretty well on time i did want to just go through a few of the slides these will be really quick um so taking this um so once you get through again you get through this you're like yeah cool dapper is great how can i implement it on some kind of live applications first i wanted to share that um dapper um where again dapper is focused on the 95 which is the queries commands and object mapping there are other packages that exist where people are are attempting to extend some of the functionality that are in orms so here's here's that same table i showed earlier with a few different properties of dapper.mapper works with helping to build the relationships between objects dapperdoc and trib um offers you it gives you the ability to provide change tracking on some of your entities so that that may be something you want to look at so some of these numbers i think need to be updated but here's an example of some others again if you just search dapper and nougat you'll see some of the additional properties and i'm sorry the additional packages that are available to you as a developer um if i can i can't remember if i asked this before last last time i'll ask you by show of hands how many people are working on cloud-based applications i see dave eric okay okay so those of you that have raised your hands the chances are you've probably run into the concept of transient errors a bit um and so these um if you haven't or if this term is new i'm not going to read this slide for verbatim but the idea is um when you're in a cloud-based environment especially like if you're running um you know serverless architecture we're running applications as a service or database as a service for example especially if you're in those lower tiers of performance there's their their platform is moving around compute power to who needs it right so it could be that if your site's dormant but somebody else in your near vicinity wants to execute azure aws whoever they'll grab some compute power take it away apply it over there real quick and then bring it back well what happens is these transient errors occur like what happened to us in my last job at three in the morning i got the your database was unavailable and the panic that is like wait wait no why why why was that um so we learned about transient errors so they're just and they could be milliseconds but their period periods in time where your database connections will drop and you'll have temporary service interruptions as a result so what does that mean is that your code will need that you'll want to look at fault tolerance you want to look at implementing retry mechanisms um and poly is the nuget library that that will help you in that so i just wanted to share this with you i didn't have a chance to demo it today um maybe that's something we can look at in the next discussion um but paulie's is a nice way to actually build some of those um retry mechanisms next is this is and this is where i believe i mentioned it before um i i've leveraged so some of the next steps like okay i get dapper how do i how do i design this in a class library and this is one thing this is what i wanted to review and actually build a repository pattern using dapper if you're interested tomorrow um there are if you there are there are some content creators that have created this i've referenced some of these articles here of how to build a repository pattern um but even this is a hot that is a hot sports opinion there's a lot of people there like oh and don't use repository pad and use this instead so um i think researching it um but i found that it was a it was a pretty clean and easy way for us to be able to to manage and once you get the hang of it it's pretty straightforward so if you guys are having me back i would love to just sit down no slides all code and we can actually build something like that together and if anybody wants those links this is all being streamed to youtube and so it's all there for you if you just want to go look at the video that's there awesome and then i'll also i'll also put i'll make sure this latest deck is up on on my github in case anybody's interested again but i hope for that i hope tonight i've introduced dapper um as an as an alternative to or a solution for accessing data and object mapping i hope we talked a little bit about best fit scenarios i i guess my last point on that i personally just don't i don't subscribe to orms should be just in utility applications or micro orms or in this world um i think it's a little bit more open-ended i sound like a consultant like well it depends um but um i believe you just have to look at multiple factors i think to make that determination um and you want to dive in more i have some additional references here um some of these are training courses as i was diving into it and and our team was diving in and learning more about dapper i have this information here um there's a couple articles that i reference within the talk and uh that's my github repo and again all the the sample code is out there um i'll just i'll update the slide deck and i'll try to get that up there by um by tomorrow morning hopefully i get it done tonight after the session but um i really thank you and appreciate your time i hope this i hope this is you know something that you're interested in and or maybe has peaks of interest and if anybody has any questions i'm happy to answer and try to answer them uh thank you scott there was one question left over i don't think we asked does dapper support sql encryption i was i was going to answer yes but i guess it depends if if the encryption is outside if it's outside of so let me preface it i i have not run into a scenario where the the the data by the time dapper pulls it back that data has been decrypted and so um i don't know if others on the the on the the squad can er on this this meeting can answer if they've run into it before um so i have not encountered that so i apologize i don't know the exact answer um i don't i don't want to blindly say i believe so um but i think that's that's a great research topic that i'll see what i can find out i hate just let me say yes and be wrong or blindly say no and be wrong oh one more question uh can we run queries in parallel in decker uh yes so um in um so yes you totally can so for example we have we have apis where we're running this and you know you can handle concurrent connections oh you can also wire up all of those extension methods i showed there are async values of each one of those um so you can run those asynchronously as well so and it works well in the again we have an infrastructure of class libraries that serve as our infrastructure layer that's called by our core layer and which which is then uh you know called through the web you know like web api for example so yes you can thanks right that's it for the questions okay thank you scott we really appreciate you coming and presenting um anybody have any last questions before we dismiss if you haven't yet please uh if you're in our slack channel go in and vote on next month's topic and if you're not in our slack channel you can join the slack channel uh it's in the the link to join that is in the comments and so if you go um vote on that i'd appreciate it i'll be sending that on to our speaker next month soon uh any last notes from you david or scott so one one thing is that if you are not in our uh slack organization you can get on our slack organization by going to north dallas.net and we have a link to it on the right hand side yep and russell just put it again in the chat so yep there you go got that too good job russell all right well thanks everybody once again join our slack workspace right there really appreciate it yeah i was looking for it yes it's uh meetings and locations right down below a little bit there oh yeah okay yep right there that's it awesome all right so there you go great thank you so much if anybody has any questions or feedback i absolutely would love to hear it so thank you very much see you later take care everybody
Info
Channel: North Dallas Developers Group
Views: 3,976
Rating: undefined out of 5
Keywords:
Id: 0oJN2HeWMEg
Channel Id: undefined
Length: 99min 2sec (5942 seconds)
Published: Thu Feb 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.