1 00:00:00,170 --> 00:00:03,480 I saw a bird recently that I couldn't identify. 2 00:00:03,480 --> 00:00:05,050 I've got some clues though. 3 00:00:05,050 --> 00:00:09,260 It was blue, brown, and black, and it was medium size. 4 00:00:09,260 --> 00:00:11,330 And I saw the bird in the United States. 5 00:00:12,880 --> 00:00:15,520 We can build a search feature for our bird data so 6 00:00:15,520 --> 00:00:17,840 that we can find out what bird it was I saw. 7 00:00:18,860 --> 00:00:21,810 Think about a typical advanced search scenario. 8 00:00:21,810 --> 00:00:25,765 There's probably multiple text boxes with different labels on them. 9 00:00:25,765 --> 00:00:31,680 Maybe a drop down list for size that gives options for tiny, small, medium, or large. 10 00:00:31,680 --> 00:00:37,000 The text boxes are for string inputs, like bird name, colors, and location. 11 00:00:37,000 --> 00:00:40,580 And then there's probably a Go button to initiate the search, and 12 00:00:40,580 --> 00:00:44,030 then it should return a list of birds that match the search parameters. 13 00:00:44,030 --> 00:00:47,468 And probably not all of them at once, but ten at a time. 14 00:00:47,468 --> 00:00:51,510 And we need to click next or previous to browse the results, and 15 00:00:51,510 --> 00:00:56,460 sometimes there's an option to view more than 10, like 50 or 100. 16 00:00:56,460 --> 00:00:59,770 Let's check out how we would implement that search feature using link and 17 00:00:59,770 --> 00:01:00,410 our bird data. 18 00:01:01,630 --> 00:01:04,120 Okay, we're back in Workspaces. 19 00:01:04,120 --> 00:01:07,996 Let's create a new file called BirdSearchExtension. 20 00:01:07,996 --> 00:01:14,753 New File > BirdSearchExtension.cs. 21 00:01:18,367 --> 00:01:24,410 Then let's put in the namespace, which is Birdwatcher, 22 00:01:24,410 --> 00:01:29,465 and we can create a new class called bird search, 23 00:01:29,465 --> 00:01:32,320 Public class BirdSearch. 24 00:01:36,220 --> 00:01:40,140 So it’s duty will be to hold the search data will pass into our yet 25 00:01:40,140 --> 00:01:41,690 to be implemented search feature. 26 00:01:42,700 --> 00:01:44,260 Let’s give it some properties. 27 00:01:44,260 --> 00:01:50,656 Public string CommonName, get set. 28 00:01:50,656 --> 00:01:56,371 Public List of strings for 29 00:01:56,371 --> 00:01:59,747 the colors, so 30 00:01:59,747 --> 00:02:05,461 list of strings, color, 31 00:02:05,461 --> 00:02:11,694 get set and a string again for 32 00:02:11,694 --> 00:02:15,608 Country get set. 33 00:02:15,608 --> 00:02:19,705 And public string Size, 34 00:02:19,705 --> 00:02:26,150 that's the size of the bird, get set. 35 00:02:26,150 --> 00:02:31,542 And then our page and page size, 36 00:02:31,542 --> 00:02:36,934 so we'll do a public int Page for 37 00:02:36,934 --> 00:02:39,930 page number, and 38 00:02:39,930 --> 00:02:45,179 a public int PageSize get set. 39 00:02:45,179 --> 00:02:48,420 Okay, now, remember that the link 40 00:02:48,420 --> 00:02:53,510 is just a bunch of extension methods tacked onto the i numeral interface. 41 00:02:53,510 --> 00:02:57,920 We can write our own extension method to search for birds, so 42 00:02:57,920 --> 00:03:00,930 we'll need a new static class in here. 43 00:03:00,930 --> 00:03:03,990 Let's call it BirdSearchExtension. 44 00:03:03,990 --> 00:03:07,625 Public static class, 45 00:03:07,625 --> 00:03:11,648 BirdSearchExtension. 46 00:03:14,447 --> 00:03:20,847 And so inside this class, our extension method will also need to be static, 47 00:03:20,847 --> 00:03:28,256 so public static and let's call it search, and it'll return an i innumerable of bird. 48 00:03:28,256 --> 00:03:31,547 IEnumerable of Bird, and 49 00:03:31,547 --> 00:03:35,889 Search for the name of the method. 50 00:03:37,220 --> 00:03:42,180 So now, since this is an extension method, the first parameter will be the object 51 00:03:42,180 --> 00:03:47,180 from which it's called, which is also going to be an IEnumerable of bird. 52 00:03:47,180 --> 00:03:51,426 And we need to use the this modifier to indicate that it's an extension method, 53 00:03:51,426 --> 00:04:00,030 this IEnumerable of Bird. 54 00:04:00,030 --> 00:04:03,865 And we'll call it source if you remember from the documentation, 55 00:04:03,865 --> 00:04:05,651 that's how Microsoft did it. 56 00:04:05,651 --> 00:04:11,267 And then we'll pass in for our second parameter our BirdSearch, 57 00:04:11,267 --> 00:04:13,830 and we'll call that search. 58 00:04:16,480 --> 00:04:24,060 Okay, let's see if we can do our entire search in one link expression. 59 00:04:24,060 --> 00:04:28,960 That'll start out with a return, and then from the source. 60 00:04:30,500 --> 00:04:34,104 We can start out by filtering with common name, 61 00:04:34,104 --> 00:04:40,080 return source.Where I'll use s for 62 00:04:40,080 --> 00:04:45,500 source, so s is an element inside the source enumerable. 63 00:04:46,570 --> 00:04:51,794 S goes to s.CommonName == search, 64 00:04:51,794 --> 00:04:57,677 which is our bird search, .CommonName. 65 00:04:59,576 --> 00:05:03,905 What about if someone entered a partial name like the first three letters, 66 00:05:03,905 --> 00:05:08,630 we should use the string method contains to return on a partial match. 67 00:05:08,630 --> 00:05:09,976 So let's redo that. 68 00:05:12,362 --> 00:05:18,153 Where s.CommonName.contains 69 00:05:18,153 --> 00:05:22,290 search.CommonName. 70 00:05:24,715 --> 00:05:27,890 That way, if I entered in S-P-A, it would return sparrows. 71 00:05:29,980 --> 00:05:33,360 Well, what if somebody left the field for name blank? 72 00:05:34,610 --> 00:05:37,990 When we search for my bird, we don't know what the name is, so 73 00:05:37,990 --> 00:05:42,670 we'll need to check if the search common name property is null first. 74 00:05:44,700 --> 00:05:50,527 So where S goes to search.CommonName 75 00:05:50,527 --> 00:05:55,290 == null or it has a match. 76 00:05:55,290 --> 00:05:55,920 That looks good. 77 00:05:57,190 --> 00:05:59,760 Next let's write another where clause for the country. 78 00:06:01,120 --> 00:06:05,910 I like to line up my link methods together like this. 79 00:06:05,910 --> 00:06:13,749 Where s goes to and we'll check also if the country's null, 80 00:06:13,749 --> 00:06:18,600 so search.Country == null or s. 81 00:06:18,600 --> 00:06:22,632 Now, the country property is actually not on the bird itself, but 82 00:06:22,632 --> 00:06:26,810 it's on the habitat, and let's go check out that class real quick. 83 00:06:29,860 --> 00:06:34,889 Here we've got a list of places as habitats, so 84 00:06:34,889 --> 00:06:40,184 it's got a list of habitats which are type place. 85 00:06:40,184 --> 00:06:45,334 So let's check out the Place class and it's gotta string of countries, 86 00:06:45,334 --> 00:06:48,890 so we're gonna have to use the any operator here. 87 00:06:48,890 --> 00:06:54,221 So where the bird, which is the S its habitats, 88 00:06:54,221 --> 00:06:56,897 are there any of those? 89 00:06:56,897 --> 00:07:02,760 We use h here for habitat, h goes to h.Country. 90 00:07:02,760 --> 00:07:11,800 We'll do a partial match on that too, contains search.Country. 91 00:07:11,800 --> 00:07:14,540 Okay, that looks good. 92 00:07:14,540 --> 00:07:21,267 Now, let's do our size parameter where S goes to. 93 00:07:21,267 --> 00:07:23,920 We'll also check and make sure it's not null. 94 00:07:26,666 --> 00:07:31,120 Or this time I think we'll do an exact match. 95 00:07:31,120 --> 00:07:35,053 B.size == 96 00:07:35,053 --> 00:07:40,060 search.Size. 97 00:07:40,060 --> 00:07:42,290 Okay, next we need to narrow down by colors. 98 00:07:42,290 --> 00:07:46,290 This is gonna be a little trickier because we've got multiple color fields on our 99 00:07:46,290 --> 00:07:50,700 bird class and the bird search variable has a list of possible colours. 100 00:07:51,880 --> 00:07:54,011 We'll start out with primary colour. 101 00:07:54,011 --> 00:07:57,180 If any of our search colors is the primary color, 102 00:07:57,180 --> 00:08:00,283 we'll want to include that bird in the result. 103 00:08:00,283 --> 00:08:02,852 Ha, I just saw the operator we should use, any. 104 00:08:02,852 --> 00:08:07,688 But since we want to return birds, if the colors match any of the primary, 105 00:08:07,688 --> 00:08:09,872 secondary or tertiary colours, 106 00:08:09,872 --> 00:08:14,637 we'll want to put all of those conditions within the same where clause. 107 00:08:17,125 --> 00:08:22,631 So .Where(s goes to, we'll start 108 00:08:22,631 --> 00:08:27,783 out with the search.Colors if any 109 00:08:27,783 --> 00:08:32,755 of those where c, we'll use c for 110 00:08:32,755 --> 00:08:38,640 color goes to c == s.PrimaryColor. 111 00:08:38,640 --> 00:08:44,624 All right, but we won't close the where just then, 112 00:08:44,624 --> 00:08:51,288 we're gonna put in or because if it's the primary color or 113 00:08:51,288 --> 00:08:56,473 the secondary color, we wanna return both. 114 00:08:56,473 --> 00:09:01,442 So S goes to search.Colors.Any where c goes to 115 00:09:01,442 --> 00:09:05,673 same deal == SecondaryColor, okay. 116 00:09:05,673 --> 00:09:10,133 Missed my s or so now we have to figure 117 00:09:10,133 --> 00:09:15,050 out how to handle the tertiary colors. 118 00:09:16,320 --> 00:09:20,280 Since we need to compare a list of colors with another list of colors, 119 00:09:20,280 --> 00:09:22,030 it sounds like we need to use a join. 120 00:09:23,110 --> 00:09:23,930 Let's try that out. 121 00:09:25,155 --> 00:09:29,260 Ope, looks like I've specified that too many times, good thing I caught that. 122 00:09:30,590 --> 00:09:33,320 Okay, so we don't need the s goes to. 123 00:09:33,320 --> 00:09:38,590 We can start right there and say where the search.Colors, 124 00:09:38,590 --> 00:09:42,930 then we'll join the list of colors from the search parameters 125 00:09:44,340 --> 00:09:48,840 to s.TeriaryColors. 126 00:09:48,840 --> 00:09:55,050 And we'll say sc for search color goes to sc, and then 127 00:09:56,380 --> 00:10:01,570 tc for tertiary colors goes to tc, those are just a list of strings. 128 00:10:01,570 --> 00:10:05,730 So we don't need to use any properties for the key selectors. 129 00:10:05,730 --> 00:10:09,747 Now, for our result, 130 00:10:09,747 --> 00:10:16,309 both parameters sc and tc goes to sc. 131 00:10:17,400 --> 00:10:19,470 So when we join the search colors and 132 00:10:19,470 --> 00:10:24,940 the tertiary colors together, if there's a match, it will return the matching color. 133 00:10:24,940 --> 00:10:29,490 And all we care about is if there's at least one, so we can tack on the any 134 00:10:29,490 --> 00:10:35,760 operator to return a boolean if that's the case, .Any. 135 00:10:35,760 --> 00:10:39,880 Okay, so all of our colors are in our filter. 136 00:10:40,950 --> 00:10:45,410 Finally, we need to deal with the page and page size perimeters. 137 00:10:45,410 --> 00:10:48,290 Do you remember the operators skip and take? 138 00:10:48,290 --> 00:10:51,570 Skip will skip a number of elements in the sequence and 139 00:10:51,570 --> 00:10:54,585 take will specify how many elements to return. 140 00:10:54,585 --> 00:11:00,108 So .Skip page 141 00:11:00,108 --> 00:11:05,633 * pageSize. 142 00:11:05,633 --> 00:11:11,267 So we're gonna start out on page zero, and when we use a page size of say five, 143 00:11:11,267 --> 00:11:16,720 zero times five is zero, so it's not gonna skip any of the elements. 144 00:11:16,720 --> 00:11:21,952 But once we advance to page one, page it would be one, pageSize will be five. 145 00:11:21,952 --> 00:11:25,560 It'll skip ahead five elements and that'll bring us to the next page. 146 00:11:27,240 --> 00:11:32,090 Then, our final take, and that'll just be the pageSize. 147 00:11:32,090 --> 00:11:36,270 So if pageSize is five, then we'll take five elements. 148 00:11:37,950 --> 00:11:42,950 And we did it, we put all of our search logic into one link expression. 149 00:11:42,950 --> 00:11:43,600 Awesome job.