Introduction

Artificial intelligence can simplify and speed up the process of writing code. One of the great tools for backend developers is the assistant built into Visual Studio from Microsoft called GitHub Copilot. Its core feature is that you have a separate window where you can ask questions about the code you have written or ask for advice on solving a given problem. It also allows you to refer to specific files or even lines of code, which ultimately helps you figure out the problem faster.   

In this article, we will talk about GitHub Copilot and analyze several examples of its use and the nuances of working with it.

Setting up GitHub Copilot

The first thing you need to do is create a GitHub account at https://github.com/signup?source=login. But if you already have an account, you can use your existing one. We are using Visual Studio version 17.12.3:

Setting up GitHub Copilot

After you have created an account, do the following: 

1. Log in to Visual Studio using this account:

how to set up GitHub Copilot

As soon as you have done this, you will be redirected to the authorization window:

how to sign in to GitHub copilot

2. Select the user to authorize at Visual Studio:

Github Copilot Visual Studio logging into the system

As soon as you have done this, you will be redirected to the authorized application:

Github copilot logging in

3. Return to Visual Studio after you have successfully been authorized:

Github copilot visual studio logging in

Having come back to Visual Studio, you will notice there a green check mark next to GitHub Copilot:

Github Copilot Visual Studio logging into the system

Now, we can use GitHub Copilot. We tested it with a paid plan, but you can use the free one (for more details, see https://github.com/features/copilot/plans?cft=copilot_lo.features_copilot).

Usage Examples

You can ask Copilot to write an example code to create a record in the Account table in Microsoft Dynamics 365:

Github Copilot visual studio chat

Here is the code to create an account record:

How To code with Github Copilot Visual Studio

You can see that, at first, GitHub Copilot tries to reference the existing code and does not give the desired result. After clarifying the query, it already offers a code example. You can ask it to modify the example and output a line with a connection to the configuration file:

How to Use GitHub Copilot Visual Studio guide

How to Use GitHub Copilot Visual Studio

How to Use GitHub Copilot Visual Studio code

Click on the Preview button and see what changes GitHub Copilot will suggest:

guide How to Use GitHub Copilot Visual Studio

The first thing that catches your eye is the modified lines 9 and 10. If you have worked with Git, then you will not have to get used to it, because all changes are displayed similarly to the version control system – git: on the left, you see the lines that were before the changes, and on the right – the lines after the changes. You can accept the changes if they suit you or reject them if they do not fully meet your requirements.

You can also write a query while reviewing the changes and ask Copilot to add more lines of code or fix the errors you see. This suggestion suits us, so we will accept the proposed changes.

Since you have modified the Program.cs class to read the connection string from the configuration file, you also need to modify the App.config file.

Now, you are in the Program.cs class. If you click the Preview button from Step 2, you will get the following result:

How To Use Github Copilot Visual Studio detailed instructions

GitHub Copilot has modified the class you are in. It is unacceptable for you, so you must reject the changes. If you go to App.config and click on "Preview", the changes will satisfy you, but do not forget to ask GitHub Copilot to rename the CrmConnectionString to Dev:

How To Use Github Copilot Visual Studio - Program.cs explanation

Program.cs in Github Copilot Visual Studio

Now, you can accept the changes. You will get the following:

how to configure Program.cs in Github Copilot Visual Studio

This time, you can see that it has inserted lines in the middle of another text, and you can see there are errors that will not allow your program to work correctly. You should ask Copilot to fix the errors:

Program.cs in Github Copilot Visual Studio instructions

Now, everything is fine. There are no errors, so you can go on working. Offer Copilot to check the App.config, modify the connection string, and move the logic for creating the record to a separate method:

Program.cs in Github Copilot Visual Studio

It has coped well with the task. Now, ask Copilot to create a separate class to work with the Account table:

GitHub Copilot Chat

If you are asked to create a new class, you have another option: “Insert in a new file”. Choose it:

how to use GitHub Copilot Chat

Also, at the end of its answer, you see that Copilot has added 2 more methods that it thinks might be useful:

GitHub Copilot Chat - instructions

As you can see, GitHub Copilot does a great job of writing simple code, but you can try to create something more complex. For example, you have a CSV file that contains data about cars and drivers:

GitHub Copilot code generation

You want to create an Excel file using the above file. If you do not wish to have 2 columns with phone numbers, ask to merge them into one. Also, write that you want to have only numbers in the TELEPHONE column. Symbols like +,-,/, and the other ones should be removed.  

! Note. After creating an Excel file, you can read it out and create contacts in CRM. If you do not have a phone number, an email address, a first name, or a last name, you cannot create a contact. Instead, you will store all the data in the memory, and after processing the Excel file, the results will be displayed on the screen.

! Note. The information from the CAR and VIN columns should be stored in the comment field on the contact.  

Run the following queries and test the code. Here is the query:

• "We have a CSV file. We want to read it and create an Excel file."

Copilot outputs the following code:

how to write code with GitHub Copilot

using System; 
using System.Collections.Generic; 
using System.IO; 
using CsvHelper; 
using OfficeOpenXml; 
using System.Globalization; 
using System.Linq;   

public class CsvToExcelConverter 
{ 
    public void ConvertCsvToExcel(string csvFilePath, string excelFilePath) 
    { 
        // Read CSV file 
        var records = new List<dynamic>(); 
        using (var reader = new StreamReader(csvFilePath)) 
        using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) 
        { 
            records = csv.GetRecords<dynamic>().ToList(); 
        }
 
        // Create Excel file 
        using (var package = new ExcelPackage()) 
        { 
            var worksheet = package.Workbook.Worksheets.Add("Sheet1");

            // Add header 
            var headerRow = records[0] as IDictionary<string, object>; 
            int colIndex = 1; 
            foreach (var header in headerRow.Keys) 
            { 
                worksheet.Cells[1, colIndex].Value = header; 
                colIndex++; 
            } 

            // Add data 
            int rowIndex = 2; 
            foreach (var record in records) 
            { 
                colIndex = 1; 
                foreach (var value in record) 
                { 
                    worksheet.Cells[rowIndex, colIndex].Value = value.Value; 
                    colIndex++; 
                } 
                rowIndex++; 
            }

            // Save Excel file 
            package.SaveAs(new FileInfo(excelFilePath)); 
        } 
    } 
}

The code looks completely working, but after running it possesses errors:

GitHub Copilot for developers - how to use

Click on “Ask Copilot” to help you figure out the problem. It will create a new session in which it will offer the following solution:

GitHub Copilot prompts

Yes, its advice was useful, now the code works. At the output, you have an Excel file, but the result does not satisfy you:

Github Copilot Chat - how to transfer csv file

You want to have separate columns, similar to those in the CSV file. You provide the following query: 

• This is a good solution, but if in the CSV file I have several columns, I want to have several columns in the Excel file, too.  

But Copilot does not give the desired results. Try to provide it with a little more information:

• The first line is a line with titles. I want to separate it. If I have columns VIN and CAR, I want the same columns in the Excel file.

Copilot produces the following code:

using System;
using System.Collections.Generic;
using System.IO;
using CsvHelper;
using OfficeOpenXml;
using System.Globalization;
using System.Linq;

public class CsvToExcelConverter
{
    public void ConvertCsvToExcel(string csvFilePath, string excelFilePath)
    {

        // Set the license context
        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

        // Read CSV file
        var records = new List<dynamic>();
        using (var reader = new StreamReader(csvFilePath))
        using (var csv = new CsvReader(reader, new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
        {
            Delimiter = ";",
            HasHeaderRecord = true
        }))
        {
            records = csv.GetRecords<dynamic>().ToList();
        }

        // Create Excel file
        using (var package = new ExcelPackage())
        {
            var worksheet = package.Workbook.Worksheets.Add("Sheet1");

            // Add header
            var headerRow = records[0] as IDictionary<string, object>;
            int colIndex = 1;
            foreach (var header in headerRow.Keys)
            {
                worksheet.Cells[1, colIndex].Value = header;
                colIndex++;
            }

            // Add data
            int rowIndex = 2;
            foreach (var record in records)
            {
                colIndex = 1;
                var recordDict = record as IDictionary<string, object>;
                foreach (var value in recordDict.Values)
                {
                    worksheet.Cells[rowIndex, colIndex].Value = value;
                    colIndex++;
                }
                rowIndex++; 
            }

            // Save Excel file
            package.SaveAs(new FileInfo(excelFilePath));
        }
    }
}

Now, the results you have received are not bad:

Github Copilot Chat - how to use data

Some data is miswritten, but do not worry. The subsequent iterations will improve the results.

Ask Copilot to do the following:

 • In the CSV file, there are 2 columns with telephone numbers (TELEPHONE 1, TELEPHONE 2), please, merge them. Also, I want to have only numbers in the TELEPHONE column in the Excel file.

 As a result, the columns have been merged but written in the EMAIL column:

how to use data in Github Copilot

Now, raise such queries:

• But you need to create a new TELEPHONE column instead of saving the result in the EMAIL column.

• No, now rename EMAIL to TELEPHONE 1 and save the result in TELEPHONE 2. As a result, we have an empty EMAIL column and a new empty column with the name TELEPHONE. But we need an EMAIL column with emails and only one TELEPHONE column.

This time, you get the desired result:

GitHub Copilot use cases

Now, you need to read out the Excel file and create contacts in CRM. To do this, you may use such queries:

how GitHub Copilot works

how to write code in Github Copilot Visual Studio

Github Copilot Visual Studio - use cases

Github Copilot Visual Studio refernces

Github Copilot chat - how to use

Github Copilot chat guide

how to use Github Copilot chat guide

how to use Github Copilot chat - instructions

Github Copilot assistance for developers

How To Use Github Copilot Visual Studio

After performing all the recommendations, you have launched your program and received these results: the contacts have been successfully created in CRM, and the records with the missing data have been displayed on the screen at the end of the program.

transfering data into CRM with GitHub Copilot

how to transfer contacts into CRM with GitHub Copilot

Thus, using GitHub Copilot, the CsvToExcelConverter.cs class has been created:

using System;
using System.Collections.Generic;
using System.IO;
using CsvHelper;
using OfficeOpenXml;
using System.Globalization;
using System.Linq;
using GitHubCopilot;

public class CsvToExcelConverter
{ 
    private readonly ContactService _contactService;

    public CsvToExcelConverter(ContactService contactService)
    {
        _contactService = contactService ?? throw new ArgumentNullException(nameof(contactService));
    }
    public void ConvertCsvToExcel(string csvFilePath, string excelFilePath)
    {
        // Set the license context
        ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
        // Read CSV file
        var records = new List<dynamic>();
        using (var reader = new StreamReader(csvFilePath))
        using (var csv = new CsvReader(reader, new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
        {
            Delimiter = ";",
            HasHeaderRecord = true
        }))
        {
            records = csv.GetRecords<dynamic>().ToList();
        }
        // Create Excel file
        using (var package = new ExcelPackage())
        {
            var worksheet = package.Workbook.Worksheets.Add("Sheet1");
            // Add header
            var headerRow = records[0] as IDictionary<string, object>;
            int colIndex = 1;
            foreach (var header in headerRow.Keys)
            {
                if (header != "TELEPHONE 1" && header != "TELEPHONE 2")
                {
                    worksheet.Cells[1, colIndex].Value = header;
                    colIndex++;
                }
            }
            worksheet.Cells[1, colIndex].Value = "TELEPHONE";
            // Add data
            int rowIndex = 2;
            foreach (var record in records)
            {
                colIndex = 1;
                var recordDict = record as IDictionary<string, object>;
                string mergedTelephone = string.Empty;
                foreach (var kvp in recordDict)
                {
                    if (kvp.Key == "TELEPHONE 1" || kvp.Key == "TELEPHONE 2")
                    {
                        mergedTelephone += new string(kvp.Value.ToString().Where(char.IsDigit).ToArray());
                    }
                    else
                    {
                        worksheet.Cells[rowIndex, colIndex].Value = kvp.Value;
                        colIndex++;
                    }
                }
                worksheet.Cells[rowIndex, colIndex].Value = mergedTelephone;
                rowIndex++;
            }
            // Save Excel file
            package.SaveAs(new FileInfo(excelFilePath));
        }
    }
    public List<dynamic> ReadExcelAndCreateContacts(string excelFilePath)
    {
        var invalidRecords = new List<dynamic>();
        using (var package = new ExcelPackage(new FileInfo(excelFilePath)))
        {
            var worksheet = package.Workbook.Worksheets[0];
            int rowCount = worksheet.Dimension.Rows;
            int colCount = worksheet.Dimension.Columns;
            for (int row = 2; row <= rowCount; row++)
            {
                var car = worksheet.Cells[row, 1].Text;
                var vin = worksheet.Cells[row, 2].Text;
                var firstName = worksheet.Cells[row, 3].Text;
                var lastName = worksheet.Cells[row, 4].Text;
                var email = worksheet.Cells[row, 5].Text;
                var telephone = worksheet.Cells[row, 6].Text;
                if (string.IsNullOrWhiteSpace(firstName) || string.IsNullOrWhiteSpace(lastName) || string.IsNullOrWhiteSpace(email) || string.IsNullOrWhiteSpace(telephone))
                {
                    invalidRecords.Add(new
                    {
                        CAR = car,
                        VIN = vin,
                        DRIVER_FIRSTNAME = firstName,
                        DRIVER_LASTNAME = lastName,
                        EMAIL = email,
                        TELEPHONE = telephone
                    });
                }
                else
                {
                    string comments = $"CAR: {car}, VIN: {vin}";
                    try
                    {
                        _contactService.CreateContactRecord(firstName, lastName, email, telephone, comments);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Error creating contact for driver {firstName} {lastName}: {ex.Message}");
                    }
                }
            }
        }
        return invalidRecords;
    }
}

Besides, the class ContactService.cs has been created:

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Tooling.Connector;
using System;

namespace GitHubCopilot
{
    public class ContactService
    {
        private readonly CrmServiceClient _service;

        public ContactService(CrmServiceClient service) 
        {
            _service = service ?? throw new ArgumentNullException(nameof(service));
        }  

        public Guid CreateContactRecord(string firstName, string lastName, string email, string telephone, string comments)
        {

            // Create a new contact entity
            Entity contact = new Entity("contact");
            contact["firstname"] = firstName;
            contact["lastname"] = lastName;
            contact["emailaddress1"] = email;
            contact["telephone1"] = telephone;
            contact["description"] = comments;

            // Create the contact record in CRM
            return _service.Create(contact);
        }
    }
}

Finally, the CSV file has been successfully converted to an Excel file, and the corresponding records have been created in CRM.

Summarizing

As you have seen above, Copilot successfully copes with routine tasks and non-standard requests. We have not composed a single line of code. Instead, we have used only the generated material. Of course, some problems have arisen while writing prompts, but the task has been completed flawlessly.  

Therefore, we can conclude that GitHub Copilot is a powerful assistant for writing code. It perfectly understands the relationships between the files that we refer to in requests. Copilot also understands the context, and if you ask it to fix it in a specific place, referring to specific lines, it easily copes with this task. However, you ought to be careful, as it may insert lines incorrectly or not show obvious errors.

Do not hesitate to contact a UDS Systems representative if you have any questions or require a consultation on the topic.