Hi there, my name is Zoran Horvat.
In this video, I will show you how you can use the GitHub Copilot tool
to help you write some realistic ASP.NET code in an application that
is also using Entity Framework Core. Copilot is an AI-backed tool
that helps you write code. It generates code for you.
But you must navigate it, you must help it understand what your needs are,
what is the specification of the problem you are solving, if you expected to write the code that
makes sense and that is, by the way, correct. This is the Web application
that models a bookstore. This is the page that displays
all the books we have. And this row at the top, it is
the feature we will discuss today. Buckle up your seat belts, I will
show you every single line of code developing a feature in a realistic ASP.NET
application with Entity Framework Core. There will be a lot of code, so let's begin.
And this is the Razor page we need to edit. We need to add those buttons at the top, each
button having one letter for an author of the book that really exists in the database.
And I want Copilot to generate those buttons for me.
I really expect this tool to write some code for me.
How do I tell it the intention? One good way of working with Copilot is
to write your intention in a comment. Look here - buttons for books.
Oh, by author initial letter. It guessed it right.
How did it do that? I believe - I cannot prove that, but I
believe - it is because I have added that parameter at the top: authorInitialLetter.
So, I did make that phrase, and it looks like Copilot has caught
that up and used it in the sentence. So, it has helped me write the request and then it
will help me write the rest of the code according to that request.
Good, very good. What is good in this piece of code?
Column span three - precisely! Iterating through the model - very
good, so there will be multiple letters. It did understand that there could
be multiple letters to filter. Then it is formatting the URL by
adding the letter into the URL. And it is also doing the CSS job for me.
Everything I never liked with HTML - generated. Thank you very much.
And the code is over. The worst part, the nightmare of every backend
developer like me: writing HTML with CSS, done by the tool.
Thank you very much. Page model, now I feel like home, this is C#.
I will add a property getter for the initial letters.
And I need to accept the value as a parameter in the GET HTTP method handler.
But not, no, no, no... what is this? No, not this. I know, yes I was missing the
question mark, the nullable indicator. Copilot is back on the track now.
Now it figures out what I'm doing. If it were a non-nullable author initial
letter, then that's not in line with what that page is telling, that it is optional
and that is probably confusing Copilot. I shouldn't be confusing it, really.
So, this is better. And now we have the situation ready
for the next part of this page, that is, populating author initial letters.
Look at this Copilot is very close to my idea. But I already see discrepancies.
I will accept this code with Tab and fix it later. So, by this point, we have the outline of
the solution, but there is more work to do. If you just wanted to push this to
production, don't do it, it's not right. That's what I want to tell you.
You have to work closer, especially with more complicated queries like this one.
Alright, let me make a pause for a moment. If you liked this video so far and you wish other
people to find it as well, the best way to help me do that is to press the LIKE button, thank you.
And also, if you want to learn more about C# development, about GitHub Copilot and other
tools, you can subscribe to my channel and watch other videos on my channel.
There's plenty of videos there already. I want to improve this query
because this is really not right. First of all, it's not about authors.
It's about books. And watch carefully what will happen next.
I will press ENTER to step to the new line and Copilot is starting to get my idea.
I do want books that have an author, that is non-null author.
You see, the same instant I said start from the books, the tool started to change its mind and say
okay let's go from the book, what should we ask? - whether there is an author, because it still wants
to extract the first letter of the author's name. Let's move on.
New line - oh, this is a good idea. Turn authors into non-nullable
references to authors. So, this Select operator will return a sequence
of non-null Author, of Person instances. That is a very good idea because I won't have
to check for null in the rest of the query. But I don't like this part,
this is really not correct. I will delete that, press
new line, and look at this! Now, this is an important
lesson about using Copilot. If you don't like a piece of code it made, just
delete it, press new line, and wait for a moment. It will come up with a different piece of code.
It will mark that first idea as not correct. So, now it will search the other
ideas it might have about your code and suggest you something different.
It is a very useful feature of GitHub, but this expression also has issues.
First of all, you cannot use the is null operator in LINQ for Entities.
This is very important part that GitHub didn't get.
Maybe they will fix it at some time. Also, I don't want to take
character of... the first character. That might be wrong in Unicode.
I want the first letter, which might include multiple characters.
And I want one more thing. Select - and look! - Copilot has got the idea.
It says oh, yes, yes, to uppercase, yes. And the expression is now complete.
Again, this was a valuable lesson, I guess, on using Copilot.
Whenever you expect it to do something, just press ENTER, wait for a moment,
and see if it has got the idea right. If not, just start typing what you want.
It will figure your idea right, you will press TAB, complete that line, press ENTER,
and it will immediately write the next line that is following that same idea that
it already got from the previous line. It's very important that that
gets into your fingertips. And second important lesson is that if
you don't like an expression, an idea, delete it, press ENTER again, and my guess is
that Copilot will suggest something different that time because it figured out that by deleting
the code it made, you have indicated to it that that was not the right idea.
Let's manage filtering now. I will pass the optional initial
letter down to the method. Optional, null is indicating
that there is no filter. How do we implement it?
First of all, I want to extract this part, taking books, and including the author into
a separate variable which is the raw query. This query is returning all
the books with their authors. If there is the filtering logic, if there
is the filter I want to do something. I want to add the Where claus to this query.
Query becomes a query with Where, yes. I want to filter by the author's
initial, but this is really not that. Also, there is one technical requirement here.
What I'm writing here, must translate into SQL. This is LINQ to Entities, and this entire query,
whatever it is in the end, must be translatable to SQL, and must execute entirely in the
database with the minimum of database resources. So, let me try by putting it this way.
If there is a last name in the database - Copilot has got the idea right.
It is querying the last name, extracting the initial from that last name, and
comparing it to the parameter to this method. Or... very good, very good! -
because there is a continuation. New line, and yes, the entire expression,
Boolean expression is correct. This is the entire query that is
filtering by the author's initial, either taken from the last name or, if last
name doesn't exist, from the first name. The next feature: filtering
the books that have no author. So, 0 will indicate no author of the book.
Look, Copilot is reading my mind again. This expression is very good.
I will just accept it, make that other filter the else branch.
So, it's either no author, or there is another filter that is used in
the expression that we made previously. And if neither of these if instructions
is hit, the query remains intact, which means it doesn't have the Where
clause, it will return all the books. Everything is as requested.
But look at this query. It is complicated, yes, but most of it was
written by just pressing TAB, TAB, TAB and okay, accepting everything that Copilot made.
I did steer it a bit, I did make certain improvements, corrections.
Continue... I see the bug here. I see the back here.
ToUpperInvariant, just after telling everything good about Copilot,
I figured that it has injected a bug here. Turning characters to uppercase
is the databases responsibility. Therefore, in LINQ to Entities, you can only
use ToUpper and leave it to the database. Okay, let's complete HTML then.
I want one more link. And Copilot knows what I'm thinking.
It will create a link to a page with no filter because the filter is optional.
Very nice! And another for no author... not exactly that.
I will have to fix it, but alright, it was close enough, yes.
This is it. And this completes the page.
We have all the features, all the elements of this feature that were requested.
Let's run the application and see it. The books are there.
This is no filter case. Now filtering authors under the letter P.
You see, Plato, it's using the first name for the initial filter if there is no last name,
so that part of the feature is doing well. Under letter A, a lot of
Asimovs, a lot of Aristotle. Everything looks good. Of course, the filter for no author
books - these three have remained. And, ultimately, removing the filter by pressing
the All button, and all books are there. This looks complete.
And I like it! I really like how it went.
I didn't have to bother with CSS, with Bootstrap, with HTML tags if you like.
And, again, look at this query. This is the... this is fully translating into SQL.
This query is entirely executed in the database. I'm fascinated with that.
And most of it was written by Copilot. I only made a few suggestions and one bug fix.
If you wonder how these data came into the database, this database was
seeded with a lot of data about books and authors, but only in development.
If you wish to learn how I did that I also developed a feature with the full use of GitHub
Copilot and you can watch the previous video. Here is the link and there is the
link in the description as well. Thank you for watching and
see you in the next episode.