Get up to 80 % extra points for free! More info:

Lesson 13 - Diary with a database in C# .NET

In the previous lesson, Lists in C# .NET, we learned about the List collection in C# .NET. We now know that it allows us to add new items at run-time so we don't have to worry about its size. In today's tutorial, we're going to make a program that involves storing objects in a List.

At first, I was going to have us create a user database, but we've already dealt with users several times in this course. Since we now know how to deal with dates and times, we're going to make a digital diary/journal. We'll store entries into a database and print today's and tomorrow's entries. This database won't be an "actual" database, we will cover databases later on. All it will be is a List in computer memory which will allow the user to add entries, search for them by date and remove them by specifying a date and time.

Let's create a new console application and name it Diary.

The entry

First of all, we'll have to create a class whose instances we will store. Let's name it Entry. Diary entries will be related to a certain date and time. It will also contain text, e.g.: January 12, 2016 - Walk the dog. Our class might look something like this:

class Entry
{
    public DateTime Occurs { get; set; }
    public string Text { get; set; }

    public Entry (DateTime occurs, string text)
    {
        Occurs = occurs;
        Text = text;
    }

    public override string ToString()
    {
        return Occurs + " " + Text;
    }
}

All this class is meant to do is store data, so it has no methods, other than the constructor and ToString(). Notice that in the constructor, there's no need to use this as we were used to doing with attributes because now we are using capitalized properties.

The database

Since our program will be a bit more complex, we'll use multiple objects to keep things nice and neat. We've already made the entry class, now let's create a Database object in which our entries will be stored. There will be a private list as there was on the Lottery application in the previous lesson. The List will be of the Entry data type this time. Our diary will allow us to add, delete and search entries by date. Let's add the Database class to the project. It will be very similar to the Lottery app from last time:

class Database
{
    private List<Entry> entries;

    public Database()
    {
        entries = new List<Entry>();
    }

}

The class will only be used for data manipulation. It will contain an internal collection of entries that will be initialized in the constructor. We could also initialize it directly without a constructor in the attribute declaration:

private List<Entry> entries = new List<Entry>();

Now let's add some methods that will add, delete and search an entry.

Adding an entry is very simple and straightforward:

public void AddEntry(DateTime occurs, string text)
{
    entries.Add(new Entry(occurs, text));
}

As for the second method, we'll allow the user to search for entries by day. The method will return the List of found entries since there could be multiple entries per day in the database. We'll be able to search for entries both by date and time or just by date. This way, we can find entries on a particular day no matter what time they occur. We'll specify our search settings using a byTime bool parameter. If it is false, our search will be by date only. First, we'll create a List and add entries that match the given date. We'll match either full date and time if the bool parameter is true, or just the Date component of it in case the bool parameter is false. Lastly, we'll return the list containing all related entries.

public List<Entry> FindEntries(DateTime date, bool byTime)
{
    List<Entry> found = new List<Entry>();
    foreach (Entry entry in entries)
    {
        if (((byTime) && (entry.Occurs == date)) // filtered by time and date
        ||
        ((!byTime) && (entry.Occurs.Date == date.Date))) // filtered by date only
            found.Add(entry);
    }
    return found;
}

We'll finish up the class by adding a method that deletes entries based on a given time. We'll perform it using the FindEntries() method, iterating over its result and removing found entries from the list. We'll be deleting entries of a specific date and time so the second parameter of the FindEntries() method will be true:

public void DeleteEntries(DateTime date)
{
    List<Entry> found = FindEntries(date, true);
    foreach (Entry entry in found)
        entries.Remove(entry);
}

Diary

Now let's add the last class to our project, which will represent the diary itself. We'll name it Diary to keep things simple and clear. It will include methods for interacting with the user. Notice how we divide our application and encapsulate its individual parts. The List is encapsulated in the Database class which provides various methods that help handle its contents safely. Let's create a Database instance in our diary. This way, we separate the data logic from the user communication logic, and even that from other program inputs/outputs. The Diary class is supposed to interact with the user and pass the entered data to the database.

Let's add a private Database instance and initialize it in the constructor:

class Diary
{

    private Database database;

    public Diary()
    {
        database = new Database();
    }

}

Next, we'll add a ReadDateTime() utility method which prompts the user to enter a date and time and returns the DateTime instance set to the entered value. The only problem here is validating the user's input (date formats depend on your OS regional settings):

private DateTime ReadDateTime()
{
    Console.WriteLine("Enter date and time as e.g. [01/13/2016 14:00]:");
    DateTime dateTime;
    while (! DateTime.TryParse(Console.ReadLine(), out dateTime))
        Console.WriteLine("Error. Please try again: ");
    return dateTime;
}

Let's add a PrintEntries() method that will find entries for the given day and print them:

public void PrintEntries(DateTime day)
{
    List<Entry> entries = database.FindEntries(day, false);
    foreach (Entry entry in entries)
        Console.WriteLine(entry);
}

We will also need a method for prompting the user to enter a new entry and adding it to the database:

public void AddEntry()
{
    DateTime dateTime = ReadDateTime();
    Console.WriteLine("Enter the entry text:");
    string text = Console.ReadLine();
    database.AddEntry(dateTime, text);
}

Also, we still have to add methods for searching and deleting entries. The searching method will return a List of found entries (we will only search by date, time doesn't matter). We'll prompt the user to enter the date and pass it to the database. Then we'll display the result.

public void SearchEntries()
{
    // Entering the date
    DateTime dateTime = ReadDateTime();
    // Searching for entries
    List<Entry> entries = database.FindEntries(dateTime, false);
    // Printing entries
    if (entries.Count() > 0)
    {
        Console.WriteLine("Entries found: ");
        foreach (Entry entry in entries)
            Console.WriteLine(entry);
    }
    else
        // Nothing found
        Console.WriteLine("No entries were found.");
}

Deleting entries is trivial:

public void DeleteEntries()
{
    Console.WriteLine("Entries with the same exact date and time will be deleted");
    DateTime dateTime = ReadDateTime();
    database.DeleteEntries(dateTime);
}

Last of all, we'll add a method for printing a home screen, showing the current date and time and entries for today and tomorrow.

public void PrintHomeScreen()
{
    Console.Clear();
    Console.WriteLine("Welcome to your virtual diary!");
    Console.WriteLine("Today is: {0}", DateTime.Now);
    Console.WriteLine();
    // printing the home screen
    Console.WriteLine("Today:\n------");
    PrintEntries(DateTime.Today);
    Console.WriteLine();
    Console.WriteLine("Tomorrow:\n---------");
    PrintEntries(DateTime.Now.AddDays(1));
    Console.WriteLine();
}

Now we can proudly move to Program.cs and create an instance of the diary, knowing that everything will work as expected. We will add the main loop here including a response to the user's choice:

static void Main(string[] args)
{
    // diary instance
    Diary diary = new Diary();
    char choice = '0';
    // main loop
    while (choice != '4')
    {
        diary.PrintHomeScreen();
        Console.WriteLine();
        Console.WriteLine("Choose an action:");
        Console.WriteLine("1 - Add an entry");
        Console.WriteLine("2 - Search for entries");
        Console.WriteLine("3 - Delete entries");
        Console.WriteLine("4 - End");
        choice = Console.ReadKey().KeyChar;
        Console.WriteLine();
        // reaction to the choice
        switch (choice)
        {
            case '1':
                diary.AddEntry();
                break;
            case '2':
                diary.SearchEntries();
                break;
            case '3':
                diary.DeleteEntries();
                break;
            case '4':
                Console.WriteLine("Press any key to quit the program...");
                break;
            default:
                Console.WriteLine("Error. Press any key to choose another action.");
                break;
        }
        Console.ReadKey();
    }
}

The code above isn't complicated at this point since we've already made similar applications in previous lessons. I gave the finalized app to my girlfriend as a present, here's what it looks like :)

Console application
Welcome to diary!
Today is: 5/12/2016 11:34:55

Today:
-----
5/12/2016 10:00:00 Shopping - Pankrac Arcade
5/12/2016 7:30:00 PM - Pet my Yorkshire Terrier Fred

Tomorrow:
--------
5/13/2016 2:00:00 PM Go jogging


Choose an action:
1 - Add an entry
2 - Search for entries
3 - Delete entries
4 - End
2
Enter date and time as e.g. [1/13/2016 10:00]
5/15/2016
Found entries:
5/15/2016 9:30:00 Economy exam

Now you know how to use List and rest assured that it will suffice as data storage container for a quite a long time. In conclusion, I'd like to congratulate you in now being able to create in-memory databases. Use it for anything you want! You could, for example, use it on the User class from the Properties lesson or pretty much anything else. You can store articles, tasks, elephants, anything you want to manage in the database. What's up next, you may ask? Next time, in Solved tasks for OOP in C# .NET lessons 12-13, we'll be talking about interfaces. There's still a lot to learn about OOP :)

In the following exercise, Solved tasks for OOP in C# .NET lessons 12-13, we're gonna practice our knowledge from previous lessons.


 

Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.

Download

By downloading the following file, you agree to the license terms

Downloaded 130x (46.22 kB)
Application includes source codes in language C#

 

Previous article
Lists in C# .NET
All articles in this section
Object-Oriented Programming in C# .NET
Skip article
(not recommended)
Solved tasks for OOP in C# .NET lessons 12-13
Article has been written for you by David Capka Hartinger
Avatar
User rating:
3 votes
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities