00:00:04.333 --> 00:00:08.438 Makes a cool database quick. Let me find a place to put it. All
00:00:08.438 --> 00:00:11.709 right, well, here, here. Actually a couple of good
00:00:11.709 --> 00:00:12.543 examples. So.
00:00:13.793 --> 00:00:18.169 To start explaining what asno tracking actually does, you have
00:00:18.169 --> 00:00:22.129 to understand how entity framework itself handles things
00:00:22.129 --> 00:00:26.436 like database updates. So what it's actually doing. If I were
00:00:26.436 --> 00:00:30.535 to do something along the lines of I just dropped my phone
00:00:30.535 --> 00:00:32.203 directly onto the floor.
00:00:33.923 --> 00:00:39.349 If I were to do something along the lines of wait context
00:00:39.349 --> 00:00:40.753 products by ID.
00:00:41.773 --> 00:00:46.089 Uh, this random product ID dot single async figure away false,
00:00:46.089 --> 00:00:49.583 so I know I should wrap that blah blah. Who cares?
00:00:51.573 --> 00:00:55.037 This product, what it's actually doing here is obviously it's
00:00:55.037 --> 00:00:58.334 gonna go do select star from products dot product where ID
00:00:58.334 --> 00:01:01.687 equals this you know it's gonna run go run that against the
00:01:01.687 --> 00:01:02.973 database it's going to.
00:01:03.873 --> 00:01:08.106 It's going to construct a an instance of a product object and
00:01:08.106 --> 00:01:12.340 map the data from the database onto that object that I'm sure
00:01:12.340 --> 00:01:16.573 we're all familiar with. What you probably don't know is that
00:01:16.573 --> 00:01:20.943 what this is actually returning is not an instance of the exact
00:01:20.943 --> 00:01:25.177 class product. Entity framework creates a proxy of that type,
00:01:25.177 --> 00:01:29.547 which is why we have to mark all the fields as virtual on them.
00:01:29.547 --> 00:01:33.303 Is so that it can override them with tracked versions.
00:01:33.393 --> 00:01:34.533 Of those properties.
00:01:35.283 --> 00:01:40.006 And what that means is that if I go and say product dot name
00:01:40.006 --> 00:01:41.633 equals some new name.
00:01:42.853 --> 00:01:46.084 Rather than this just being a simple string assignment, this
00:01:46.084 --> 00:01:49.368 is actually telling that proxy that I've updated the property
00:01:49.368 --> 00:01:52.387 of name and then when I do context dot save unit of work
00:01:52.387 --> 00:01:55.513 which would be async normally. But just to make the point.
00:01:56.143 --> 00:01:59.846 It can now go and see that OK at some point, since you created
00:01:59.846 --> 00:02:03.197 this, since you got this context, you read out a product
00:02:03.197 --> 00:02:04.373 that we're tracking.
00:02:05.043 --> 00:02:08.736 And on that tracked record, you changed the name property to
00:02:08.736 --> 00:02:12.429 something and that this is how it will know to generate some
00:02:12.429 --> 00:02:16.122 sequel of like update products, dot products set name equals
00:02:16.122 --> 00:02:18.423 this where ID equals real product ID.
00:02:19.793 --> 00:02:23.561 So in essence, what that boils down to is this query is
00:02:23.561 --> 00:02:27.800 returning a tracked object and there is performance and memory
00:02:27.800 --> 00:02:29.483 overhead related to that.
00:02:30.443 --> 00:02:34.589 Now what? As no tracking does is it allows you to opt out of that
00:02:34.589 --> 00:02:37.982 tracking. And the reason that you would do that is in
00:02:37.982 --> 00:02:41.313 scenarios where you don't need to update the values.
00:02:42.633 --> 00:02:45.962 You don't have to pay that performance and memory cost and
00:02:45.962 --> 00:02:49.348 all you have to do is as no tracking. That being said, this
00:02:49.348 --> 00:02:52.847 exact code will now result in no changes to the database even
00:02:52.847 --> 00:02:56.233 though I am modifying the name property on this product and
00:02:56.233 --> 00:02:59.732 saving. This is an untracked entity, meaning entity framework
00:02:59.732 --> 00:03:03.005 has not has decided not to attach any information to tell
00:03:03.005 --> 00:03:06.730 it that I'm changing the name on this record. It doesn't know and
00:03:06.730 --> 00:03:07.633 it doesn't care.
00:03:08.363 --> 00:03:08.833 Umm.
00:03:10.673 --> 00:03:15.178 This can also be useful in like really tight performance related
00:03:15.178 --> 00:03:18.783 code where you want to forego the full cost of the.
00:03:20.823 --> 00:03:24.780 The update tracking, but you still want to be able to update
00:03:24.780 --> 00:03:28.803 is you can forgo tracking on the entire entity and handle the
00:03:28.803 --> 00:03:32.956 logic of knowing what needs to be updated yourself, and you can
00:03:32.956 --> 00:03:36.978 do things like this. You can do like context dot products dot
00:03:36.978 --> 00:03:37.433 attach.
00:03:40.413 --> 00:03:44.537 And attach your product. It attaches it as if nothing has
00:03:44.537 --> 00:03:49.088 been modified and then you can do context. Let's say it's yeah,
00:03:49.088 --> 00:03:51.293 dot entry product dot property.
00:03:54.143 --> 00:03:54.773 Name.
00:03:55.873 --> 00:03:59.731 And then leave it. There's like, uh, what is it is modified
00:03:59.731 --> 00:04:00.503 equals true?
00:04:01.453 --> 00:04:05.267 And so now, rather than having the memory and and performance
00:04:05.267 --> 00:04:08.711 cost of having this actually be a proxy and having this
00:04:08.711 --> 00:04:12.710 assignment be more complex than it needs to be, I can explicitly
00:04:12.710 --> 00:04:16.585 tell the context what properties on what objects are modified.
00:04:16.585 --> 00:04:20.215 Obviously this is a lot more boilerplate and messy, but if
00:04:20.215 --> 00:04:23.844 you're updating for some reason you're writing code that's
00:04:23.844 --> 00:04:27.781 updating thousands and thousands of records, and it needs to do
00:04:27.781 --> 00:04:30.673 it super fast, this is much, much faster than.
00:04:31.333 --> 00:04:33.463 That querying out the entire product.
00:04:34.383 --> 00:04:37.726 Updating the thing and then save unit of work. Another really
00:04:37.726 --> 00:04:40.693 cool thing about this is that you can do it like this.
00:04:41.673 --> 00:04:42.393 Uh.
00:04:43.833 --> 00:04:48.463 New product ID equals. So let's say that you.
00:04:49.383 --> 00:04:52.262 You know the ID of the product you need to update one exact
00:04:52.262 --> 00:04:54.997 field on and obviously you wouldn't want this to be just
00:04:54.997 --> 00:04:58.020 like passed in from the you want to validate this somehow. But
00:04:58.020 --> 00:05:01.187 let's say that you know you need to update product ID of one. You
00:05:01.187 --> 00:05:01.763 can do this.
00:05:04.743 --> 00:05:08.167 And even though you didn't read this product out from the
00:05:08.167 --> 00:05:11.296 database, you can attach it as if it were completely
00:05:11.296 --> 00:05:14.779 unmodified, and as long as you've provided the primary key
00:05:14.779 --> 00:05:18.322 for it here, this will still work, and you can do untracked
00:05:18.322 --> 00:05:20.743 product dot name equals whatever I want.
00:05:21.403 --> 00:05:22.163 And.
00:05:24.213 --> 00:05:27.083 This will actually go update.
00:05:28.113 --> 00:05:31.401 The product ID one to the to have the name of whatever I want
00:05:31.401 --> 00:05:34.317 it will. It will literally execute update products dot
00:05:34.317 --> 00:05:37.553 product set name equals whatever I want where ID equals one.
00:05:38.293 --> 00:05:42.203 Umm, so this is obviously a little bit more of a like.
00:05:43.023 --> 00:05:46.646 99% of the time, you're not gonna need to do this, but there
00:05:46.646 --> 00:05:49.972 are scenarios where this is useful in and. Also, I just
00:05:49.972 --> 00:05:50.923 think it's neat.
00:05:51.643 --> 00:05:52.453 Uh, so?
00:05:53.653 --> 00:05:57.860 But that's most of the time. All you really need to know and care
00:05:57.860 --> 00:06:01.557 about is, are you planning to update or write back to the
00:06:01.557 --> 00:06:05.381 database at all? If the answer to that question is no, just
00:06:05.381 --> 00:06:09.461 default to using as no tracking. If the answer to that question
00:06:09.461 --> 00:06:13.349 is yes or is absolutely yes, then that you are going to need
00:06:13.349 --> 00:06:16.919 to write back to the database. Then you can't use as no
00:06:16.919 --> 00:06:17.493 tracking.
00:06:20.133 --> 00:06:24.033 So one last note about the functionality of entity
00:06:24.033 --> 00:06:26.863 framework creating tracked entities.
00:06:29.473 --> 00:06:33.185 And I'll go ahead and just give myself another clean down here
00:06:33.185 --> 00:06:35.483 in case anybody wants to look at that.
00:06:36.023 --> 00:06:36.473 Umm.
00:06:38.553 --> 00:06:44.023 Some data equals away and text, not products. Goodbye ID.
00:06:46.383 --> 00:06:50.843 Act so you'll notice that I'm not using an asno tracking in
00:06:50.843 --> 00:06:55.453 this query. The reason for that is because I'm not returning.
00:06:56.243 --> 00:06:59.642 And entity type I'm not returning product. I'm not
00:06:59.642 --> 00:07:03.707 returning lot. I'm not returning customer or contact or user
00:07:03.707 --> 00:07:07.706 whatever. I'm returning a date time. Entity framework can't
00:07:07.706 --> 00:07:11.972 return a proxy date time so this can't be tracked anyway so and
00:07:11.972 --> 00:07:16.237 has no tracking isn't necessary here. This is implicitly a read
00:07:16.237 --> 00:07:20.569 only query because I'm querying for a specific column or in this
00:07:20.569 --> 00:07:20.903 case.
00:07:21.743 --> 00:07:23.003 Two columns technically.
00:07:25.413 --> 00:07:28.950 So that also goes for selecting anonymous objects. However, you
00:07:28.950 --> 00:07:32.488 should know that if you select an anonymous object and then you
00:07:32.488 --> 00:07:33.483 do something like.
00:07:35.523 --> 00:07:38.327 X dot palette. I guess I don't know the first thing that came
00:07:38.327 --> 00:07:38.463 up.
00:07:39.123 --> 00:07:43.033 Pallet is a package which is a database table. This is now
00:07:43.033 --> 00:07:47.143 attract entity unless you put as no tracking up here. So even
00:07:47.143 --> 00:07:50.788 though I'm selecting an anonymous object here which in
00:07:50.788 --> 00:07:52.313 theory doesn't need it.
00:07:56.853 --> 00:07:59.666 This anonymous object has a tracked entity inside of it,
00:07:59.666 --> 00:08:02.628 which again has the memory and performance cost. If I'm not
00:08:02.628 --> 00:08:05.787 planning on modifying anything about palette, then I should put
00:08:05.787 --> 00:08:06.923 as no tracking up here.
00:08:11.733 --> 00:08:15.802 But that being said, if this were to just be like X dot ID X
00:08:15.802 --> 00:08:16.403 dot name.
00:08:17.063 --> 00:08:20.673 Uh, description and even something more complex like.
00:08:24.153 --> 00:08:26.743 That image is that select.
00:08:34.403 --> 00:08:36.153 Original file name, sure.
00:08:38.203 --> 00:08:38.763 Umm.
00:08:39.723 --> 00:08:42.568 None of this is tracked because this is just a innumerable
00:08:42.568 --> 00:08:45.173 strings, and these are all strings or ints. Those are
00:08:45.173 --> 00:08:48.115 untractable. They're not entity types. Even on querying into
00:08:48.115 --> 00:08:50.767 other entities, I'm not returning those other entities
00:08:50.767 --> 00:08:51.443 I'm returning.
00:08:52.343 --> 00:08:55.867 And enumerable strings over or you know, or just a flat string,
00:08:55.867 --> 00:08:59.392 or a number, or whatever it is. Those are not trackable anyway,
00:08:59.392 --> 00:09:02.751 so in this case, as no tracking doesn't really matter. Again
00:09:02.751 --> 00:09:06.110 though, most of the time it's not gonna hurt anything. Well,
00:09:06.110 --> 00:09:09.360 I'm not gonna say most times it's not gonna hurt anything,
00:09:09.360 --> 00:09:12.939 ever, to just have it on there. If you don't need to write back.
00:09:12.939 --> 00:09:16.519 But it does harm performance to not have it when you do need it.
00:09:16.519 --> 00:09:19.878 So if you're ever not sure if you should have it or not, the
00:09:19.878 --> 00:09:23.293 answer is, are you gonna write anything back to the database?
00:09:23.413 --> 00:09:25.770 If not, then yes, put it on there. Even if you're returning
00:09:25.770 --> 00:09:27.303 an anonymous object that doesn't have.
00:09:28.733 --> 00:09:31.093 Anything that it's that could be written back anyway.
00:09:31.913 --> 00:09:34.644 Having this years not gonna hurt your the performance of
00:09:34.644 --> 00:09:37.712 anything. It's not gonna break anything or cause any unintended
00:09:37.712 --> 00:09:38.383 functionality.
00:09:40.103 --> 00:09:43.001 So better safe than sorry to put it on there, whether you,
00:09:43.001 --> 00:09:45.850 whether you're returning something that can be tracked or
00:09:45.850 --> 00:09:46.243 not, so.
00:09:48.003 --> 00:09:49.913 Now hopefully that.
00:09:51.533 --> 00:09:55.043 Uh made sense and was worth explaining.
00:09:55.963 --> 00:09:59.358 Yeah, that was cool. So there isn't a tracking is is a really
00:09:59.358 --> 00:10:02.753 good option if you're link query is just really to get like a
00:10:02.753 --> 00:10:04.123 piece of data that maybe.
00:10:04.763 --> 00:10:05.183 Yep.
00:10:05.063 --> 00:10:08.031 Is important to your logic that you're not actually gonna update
00:10:08.031 --> 00:10:09.813 the database as a result of that call.
00:10:08.953 --> 00:10:12.329 Right, exactly. Like you can imagine that as no tracking is
00:10:12.329 --> 00:10:15.818 almost like as read only like that's almost another good name
00:10:14.983 --> 00:10:15.243 Cool.
00:10:15.818 --> 00:10:19.533 for it. It's basically that your read only querying the database.
00:10:15.983 --> 00:10:16.303 All right.
00:10:20.703 --> 00:10:22.673 Umm so yeah.
00:10:22.733 --> 00:10:23.003 That's.