From 83338fd3b5708d39c129ea0446b673873affd77c Mon Sep 17 00:00:00 2001 From: David Mikhayelyan Date: Mon, 24 Oct 2016 15:40:23 -0500 Subject: [PATCH 01/56] What is EF and Who should use this tutorial sections --- content/efcore/README.md | 4 ++++ .../efcore/getting-started/getting-started.md | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 content/efcore/README.md create mode 100644 content/efcore/getting-started/getting-started.md diff --git a/content/efcore/README.md b/content/efcore/README.md new file mode 100644 index 0000000..978833b --- /dev/null +++ b/content/efcore/README.md @@ -0,0 +1,4 @@ +# Entity Framework Core Tutorials + +[Getting Started with Entity Framework Core](getting-started/README.md) +This tutorial covers the basics of how to get started writing your first application using Entity Framework Core. \ No newline at end of file diff --git a/content/efcore/getting-started/getting-started.md b/content/efcore/getting-started/getting-started.md new file mode 100644 index 0000000..4992aeb --- /dev/null +++ b/content/efcore/getting-started/getting-started.md @@ -0,0 +1,16 @@ +# Getting Started using Entity Framework Core +by [The Raikes School](http://cse.unl.edu/raikes-school) + +## What is Entity Framework Core? + +Entity Framework Core (EF Core) is a lightweight, extensible, and cross-platform version of Entity Framework. Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects. This allows developers to create and manage databases without most of the data-access code that developers usually need to write.  + +As a lightweight version of the original Entity Framework, EF Core does not have all the features available in the latest version of Entity Framework (EF6.x). However, EF Core does offer a few features EF6.x does not. For more on these differences, check out [the docs](https://docs.efproject.net/en/latest/efcore-vs-ef6/features.html). If you have further questions about which version is best for your project, visit ["Which One Is Right for You?"](https://docs.efproject.net/en/latest/efcore-vs-ef6/choosing.html). + +## Who is this tutorial meant for? + +This tutorial is meant for those new or unfamiliar to EF Core, but if you already have an understanding of EF Core, consider this a refresher course. This tutorial will also help you navigate EF Core if you are familiar with previous versions of EF. For those more experienced EF Core programmers, [the docs](https://docs.efproject.net/en/latest/) may be of more use to you. The docs feature higher level EF Core concepts that this tutorial does not. + +If you know what you're looking for, feel free to browse by topic on the side. If not, welcome! Let's get started together! + +## Prerequisites for this tuorial \ No newline at end of file From a9b80325d4ff7e637456901ad6061cb9a3cdbf10 Mon Sep 17 00:00:00 2001 From: David Mikhayelyan Date: Mon, 24 Oct 2016 15:53:22 -0500 Subject: [PATCH 02/56] Completed first draft of getting-started page --- content/efcore/getting-started/getting-started.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/content/efcore/getting-started/getting-started.md b/content/efcore/getting-started/getting-started.md index 4992aeb..3a1dc13 100644 --- a/content/efcore/getting-started/getting-started.md +++ b/content/efcore/getting-started/getting-started.md @@ -13,4 +13,16 @@ This tutorial is meant for those new or unfamiliar to EF Core, but if you alread If you know what you're looking for, feel free to browse by topic on the side. If not, welcome! Let's get started together! -## Prerequisites for this tuorial \ No newline at end of file +## Prerequisites for this tutorial + +This tutorial assumes a knowledge of other programming concepts, including:  + +* Basic programming concepts  +* C# (see the [interactive C# tutorial](https://www.microsoft.com/net/tutorials/csharp/getting-started)) +* Relational database concepts + - SQL-type databases will be the focus of this tutorial, though other databases function with EF Core +* LINQ statements (see this [interactive tutorial](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) for an introduction to LINQ)  + +If you're a new to these topics, you can check out their tutorials. If you're only a little rusty, we'll remind you of the relevant aspects along the way. + +Now, let's get started! \ No newline at end of file From 7962d4b1d9ad03a678007d615ae423f89d047a9c Mon Sep 17 00:00:00 2001 From: David Mikhayelyan Date: Mon, 24 Oct 2016 15:57:26 -0500 Subject: [PATCH 03/56] Changed getting-started page to the README of getting-started directory --- content/efcore/getting-started/{getting-started.md => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename content/efcore/getting-started/{getting-started.md => README.md} (100%) diff --git a/content/efcore/getting-started/getting-started.md b/content/efcore/getting-started/README.md similarity index 100% rename from content/efcore/getting-started/getting-started.md rename to content/efcore/getting-started/README.md From 0655b2a3cae7d9851391f8343f4c947c32c28a8b Mon Sep 17 00:00:00 2001 From: arynhuck Date: Tue, 25 Oct 2016 20:30:28 -0500 Subject: [PATCH 04/56] Editted README to be concise The README needed to be reorganized (some content will go into the Introduction section) and a lot of chit chat needed to be cut down. The tone is less conversational and more down-to-business (but still friendly). This will close issue #1 --- content/efcore/getting-started/README.md | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 3a1dc13..515a4d4 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -1,28 +1,23 @@ -# Getting Started using Entity Framework Core -by [The Raikes School](http://cse.unl.edu/raikes-school) - -## What is Entity Framework Core? - -Entity Framework Core (EF Core) is a lightweight, extensible, and cross-platform version of Entity Framework. Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects. This allows developers to create and manage databases without most of the data-access code that developers usually need to write.  - -As a lightweight version of the original Entity Framework, EF Core does not have all the features available in the latest version of Entity Framework (EF6.x). However, EF Core does offer a few features EF6.x does not. For more on these differences, check out [the docs](https://docs.efproject.net/en/latest/efcore-vs-ef6/features.html). If you have further questions about which version is best for your project, visit ["Which One Is Right for You?"](https://docs.efproject.net/en/latest/efcore-vs-ef6/choosing.html). +# Getting Started with Entity Framework Core ## Who is this tutorial meant for? -This tutorial is meant for those new or unfamiliar to EF Core, but if you already have an understanding of EF Core, consider this a refresher course. This tutorial will also help you navigate EF Core if you are familiar with previous versions of EF. For those more experienced EF Core programmers, [the docs](https://docs.efproject.net/en/latest/) may be of more use to you. The docs feature higher level EF Core concepts that this tutorial does not. +This tutorial is meant for those new to Entity Framework (EF) Core, but if you already have an understanding of EF Core, consider this a refresher course. More advanced functionality is covered in the [docs](https://docs.efproject.net/en/latest/) . If you know what you're looking for, feel free to browse by topic on the side. If not, welcome! Let's get started together! ## Prerequisites for this tutorial -This tutorial assumes a knowledge of other programming concepts, including:  +You should understand the following concepts before starting this tutorial:  -* Basic programming concepts  * C# (see the [interactive C# tutorial](https://www.microsoft.com/net/tutorials/csharp/getting-started)) * Relational database concepts - SQL-type databases will be the focus of this tutorial, though other databases function with EF Core -* LINQ statements (see this [interactive tutorial](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) for an introduction to LINQ)  +* LINQ statements (see this [interactive tutorial](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) for an introduction to LINQ) + +## Table of Contents -If you're a new to these topics, you can check out their tutorials. If you're only a little rusty, we'll remind you of the relevant aspects along the way. +The tutorial features the following topics: -Now, let's get started! \ No newline at end of file +* Introduction to Entity Framework Core +* Adding Entity Framework Core to a Project \ No newline at end of file From ee96fa57a30d90b75f4e3b1f6f1b36f9ef2a6364 Mon Sep 17 00:00:00 2001 From: arynhuck Date: Tue, 25 Oct 2016 20:37:06 -0500 Subject: [PATCH 05/56] Cut SQL comment We don't want to tie this EF Core tutorial to a certain type of database, so I've removed SQL as a requirement. This should make this README ready to :shipit: . #1 --- content/efcore/getting-started/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 515a4d4..a550d27 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -12,7 +12,6 @@ You should understand the following concepts before starting this tutorial: * C# (see the [interactive C# tutorial](https://www.microsoft.com/net/tutorials/csharp/getting-started)) * Relational database concepts - - SQL-type databases will be the focus of this tutorial, though other databases function with EF Core * LINQ statements (see this [interactive tutorial](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) for an introduction to LINQ) ## Table of Contents From aeef2f9ceaa74a2b7b12897abd89653424b6afdb Mon Sep 17 00:00:00 2001 From: arynhuck Date: Tue, 25 Oct 2016 20:37:59 -0500 Subject: [PATCH 06/56] Condensed sentence Yay wordiness. Took Ryan's suggestions and made the general description more concise. --- content/efcore/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/efcore/README.md b/content/efcore/README.md index 978833b..79bdd5d 100644 --- a/content/efcore/README.md +++ b/content/efcore/README.md @@ -1,4 +1,4 @@ # Entity Framework Core Tutorials [Getting Started with Entity Framework Core](getting-started/README.md) -This tutorial covers the basics of how to get started writing your first application using Entity Framework Core. \ No newline at end of file +This tutorial covers the basics of using Entity Framework Core in a C# application. \ No newline at end of file From ebff60faa601bf76b164dfb1c3d9f82717794e5e Mon Sep 17 00:00:00 2001 From: arynhuck Date: Fri, 28 Oct 2016 12:20:04 -0500 Subject: [PATCH 07/56] Changed README content, added TOC The README has been updated to be more concise and to fit with the other training-tutorials. A Table of contents has been added (when the other pages are added to the project, it will have to be updated to contain links to the markdown pages). --- content/efcore/getting-started/README.md | 19 ++----------------- content/efcore/getting-started/toc.md | 2 ++ 2 files changed, 4 insertions(+), 17 deletions(-) create mode 100644 content/efcore/getting-started/toc.md diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index a550d27..df8c892 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -1,22 +1,7 @@ # Getting Started with Entity Framework Core -## Who is this tutorial meant for? +## Who Should Read This? This tutorial is meant for those new to Entity Framework (EF) Core, but if you already have an understanding of EF Core, consider this a refresher course. More advanced functionality is covered in the [docs](https://docs.efproject.net/en/latest/) . -If you know what you're looking for, feel free to browse by topic on the side. If not, welcome! Let's get started together! - -## Prerequisites for this tutorial - -You should understand the following concepts before starting this tutorial:  - -* C# (see the [interactive C# tutorial](https://www.microsoft.com/net/tutorials/csharp/getting-started)) -* Relational database concepts -* LINQ statements (see this [interactive tutorial](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) for an introduction to LINQ) - -## Table of Contents - -The tutorial features the following topics: - -* Introduction to Entity Framework Core -* Adding Entity Framework Core to a Project \ No newline at end of file +Before beginning this tutorial, you should understand a few topics. One, this tutorial assumes a familiarity with C#. If you're new to C#, you may wish to go through the [Getting Started with C#](https://www.microsoft.com/net/tutorials/csharp/getting-started) tutorial. Two, you should have a basic knowledge of relational database concepts. Three, this tutorial will use LINQ statements. If you have not used LINQ before, the [Introducing LINQ](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) for an introduction to LINQ) tutorial can help you get up-to-speed on LINQ. diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md new file mode 100644 index 0000000..86ef74b --- /dev/null +++ b/content/efcore/getting-started/toc.md @@ -0,0 +1,2 @@ +- Introduction to Entity Framework Core +- Adding Entity Framework Core to a Project \ No newline at end of file From f5d1f89d362c9fd08a5afd2cdccd3348070bae68 Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Mon, 31 Oct 2016 15:44:22 -0500 Subject: [PATCH 08/56] added table of contents section, combined paragraphs, fixed wordingof LINQ section and where we mention more advanced functionality --- content/efcore/getting-started/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index df8c892..5ef9091 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -2,6 +2,8 @@ ## Who Should Read This? -This tutorial is meant for those new to Entity Framework (EF) Core, but if you already have an understanding of EF Core, consider this a refresher course. More advanced functionality is covered in the [docs](https://docs.efproject.net/en/latest/) . +This tutorial is meant for those new to Entity Framework (EF) Core, as it covers the basic functionalities of EF Core. More advanced functionality is covered in the [docs](https://docs.efproject.net/en/latest/) . Before beginning this tutorial, you should understand a few topics. One, this tutorial assumes a familiarity with C#. If you're new to C#, you may wish to go through the [Getting Started with C#](https://www.microsoft.com/net/tutorials/csharp/getting-started) tutorial. Two, you should have a basic knowledge of relational database concepts. Three, this tutorial will use LINQ. If you have not used LINQ before, the [Introducing LINQ](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) tutorial can help you get up-to-speed on LINQ. -Before beginning this tutorial, you should understand a few topics. One, this tutorial assumes a familiarity with C#. If you're new to C#, you may wish to go through the [Getting Started with C#](https://www.microsoft.com/net/tutorials/csharp/getting-started) tutorial. Two, you should have a basic knowledge of relational database concepts. Three, this tutorial will use LINQ statements. If you have not used LINQ before, the [Introducing LINQ](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) for an introduction to LINQ) tutorial can help you get up-to-speed on LINQ. +## Topics Covered + +This tutorial will cover the following topics: \ No newline at end of file From 99bbf2ea6fe3bbe45aa981a724d67c7e3c1c2038 Mon Sep 17 00:00:00 2001 From: arynhuck Date: Mon, 31 Oct 2016 17:57:11 -0500 Subject: [PATCH 09/56] TOC added to README Apparently Ryan wanted this. --- content/efcore/getting-started/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 5ef9091..8aabbf1 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -6,4 +6,6 @@ This tutorial is meant for those new to Entity Framework (EF) Core, as it covers ## Topics Covered -This tutorial will cover the following topics: \ No newline at end of file +This tutorial will cover the following topics: +- Introduction to Entity Framework Core +- Adding Entity Framework Core to a Project \ No newline at end of file From 916fc34ab1cfceed9b0a1d0d81606b534ac6b2d6 Mon Sep 17 00:00:00 2001 From: arynhuck Date: Mon, 31 Oct 2016 18:07:52 -0500 Subject: [PATCH 10/56] Changing how the list of prereqs looks We went with 1) 2) 3) --- content/efcore/getting-started/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 8aabbf1..6ad68b2 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -2,7 +2,7 @@ ## Who Should Read This? -This tutorial is meant for those new to Entity Framework (EF) Core, as it covers the basic functionalities of EF Core. More advanced functionality is covered in the [docs](https://docs.efproject.net/en/latest/) . Before beginning this tutorial, you should understand a few topics. One, this tutorial assumes a familiarity with C#. If you're new to C#, you may wish to go through the [Getting Started with C#](https://www.microsoft.com/net/tutorials/csharp/getting-started) tutorial. Two, you should have a basic knowledge of relational database concepts. Three, this tutorial will use LINQ. If you have not used LINQ before, the [Introducing LINQ](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) tutorial can help you get up-to-speed on LINQ. +This tutorial is meant for those new to Entity Framework (EF) Core, as it covers the basic functionalities of EF Core. More advanced functionality is covered in the [docs](https://docs.efproject.net/en/latest/) . Before beginning this tutorial, you should understand a few topics. 1) this tutorial assumes a familiarity with C#. If you're new to C#, you may wish to go through the [Getting Started with C#](https://www.microsoft.com/net/tutorials/csharp/getting-started) tutorial. 2) you should have a basic knowledge of relational database concepts. 3) this tutorial will use LINQ. If you have not used LINQ before, the [Introducing LINQ](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) tutorial can help you get up-to-speed on LINQ. ## Topics Covered From 59dc6d7512fc9ff868854e7eb1b238df09f0b34f Mon Sep 17 00:00:00 2001 From: arynhuck Date: Tue, 1 Nov 2016 15:46:13 -0500 Subject: [PATCH 11/56] Conciseness changes to README, emptying TOC We shortened the titles of articles, changed back to bullet points (the markdown supports it, we will just have to change what we give the website), and changed wordage. Emptied the TOC so nothing will freak out when it tries to parse documents that haven't been added yet. --- content/efcore/getting-started/README.md | 12 +++++++++--- content/efcore/getting-started/toc.md | 2 -- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 6ad68b2..70893de 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -2,10 +2,16 @@ ## Who Should Read This? -This tutorial is meant for those new to Entity Framework (EF) Core, as it covers the basic functionalities of EF Core. More advanced functionality is covered in the [docs](https://docs.efproject.net/en/latest/) . Before beginning this tutorial, you should understand a few topics. 1) this tutorial assumes a familiarity with C#. If you're new to C#, you may wish to go through the [Getting Started with C#](https://www.microsoft.com/net/tutorials/csharp/getting-started) tutorial. 2) you should have a basic knowledge of relational database concepts. 3) this tutorial will use LINQ. If you have not used LINQ before, the [Introducing LINQ](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq) tutorial can help you get up-to-speed on LINQ. +This tutorial is aimed at people who are learning EF Core for the first time. More advanced functionality is covered in the [docs](https://docs.efproject.net/en/latest/). Before beginning this tutorial, you should understand the following topics: + +- C# (see [Getting Started with C#](https://www.microsoft.com/net/tutorials/csharp/getting-started)) +- Relational database concepts +- LINQ (see [Introducing LINQ](https://www.microsoft.com/net/tutorials/csharp/getting-started/linq)) + ## Topics Covered This tutorial will cover the following topics: -- Introduction to Entity Framework Core -- Adding Entity Framework Core to a Project \ No newline at end of file +- Intro to EF Core +- Adding EF Core to a Project +- Querying Data \ No newline at end of file diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index 86ef74b..e69de29 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -1,2 +0,0 @@ -- Introduction to Entity Framework Core -- Adding Entity Framework Core to a Project \ No newline at end of file From 2fc72647fa9bff29a4b5fc2f6dc71799ec598b55 Mon Sep 17 00:00:00 2001 From: arynhuck Date: Thu, 27 Oct 2016 15:44:52 -0500 Subject: [PATCH 12/56] Resolves #16 - Adds Intro to EF Core chapter --- content/efcore/getting-started/README.md | 4 +--- content/efcore/getting-started/intro-to-ef-core.md | 5 +++++ content/efcore/getting-started/toc.md | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 content/efcore/getting-started/intro-to-ef-core.md diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 70893de..b4ed002 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -12,6 +12,4 @@ This tutorial is aimed at people who are learning EF Core for the first time. Mo ## Topics Covered This tutorial will cover the following topics: -- Intro to EF Core -- Adding EF Core to a Project -- Querying Data \ No newline at end of file +- [Intro to EF Core](what-is-ef-core.md) \ No newline at end of file diff --git a/content/efcore/getting-started/intro-to-ef-core.md b/content/efcore/getting-started/intro-to-ef-core.md new file mode 100644 index 0000000..6636216 --- /dev/null +++ b/content/efcore/getting-started/intro-to-ef-core.md @@ -0,0 +1,5 @@ +# Intro to EF Core + +Entity Framework Core (EF Core) is a lightweight, extensible, and cross-platform version of Entity Framework. Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects. This allows developers to create and manage databases without most of the data-access code that developers usually need to write.  + +EF Core and the latest version of Entity Framework (EF6.x) differ in the features they support. A comparison of the features supported by each can be found on the [feature comparison page](https://docs.efproject.net/en/latest/efcore-vs-ef6/features.html) of the docs. If you want help determining which version is best for your project, check out the ["Which One Is Right for You?"](https://docs.efproject.net/en/latest/efcore-vs-ef6/choosing.html) page. \ No newline at end of file diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index e69de29..1041165 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -0,0 +1 @@ +- [Intro to EF Core](what-is-ef-core.md) \ No newline at end of file From 2b8e761e19837feacf89568d5ebd37753984daa8 Mon Sep 17 00:00:00 2001 From: arynhuck Date: Thu, 3 Nov 2016 16:33:47 -0500 Subject: [PATCH 13/56] 23 Installing EF Core to a computer (#24) Resolves #23 - Installing EF Core Also fixes broken link to Intro to EF Core page in the TOC and README. --- content/efcore/getting-started/README.md | 3 +- .../getting-started/installing-ef-core.md | 56 +++++++++++++++++++ content/efcore/getting-started/toc.md | 3 +- 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 content/efcore/getting-started/installing-ef-core.md diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index b4ed002..9b1953d 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -12,4 +12,5 @@ This tutorial is aimed at people who are learning EF Core for the first time. Mo ## Topics Covered This tutorial will cover the following topics: -- [Intro to EF Core](what-is-ef-core.md) \ No newline at end of file +- [Intro to EF Core](intro-to-ef-core.md) +- [Installing EF Core](installing-ef-core.md) \ No newline at end of file diff --git a/content/efcore/getting-started/installing-ef-core.md b/content/efcore/getting-started/installing-ef-core.md new file mode 100644 index 0000000..5655e36 --- /dev/null +++ b/content/efcore/getting-started/installing-ef-core.md @@ -0,0 +1,56 @@ +# Installing EF Core + +In this lesson, you will learn how to install EF Core on your machine. You do not need to complete these steps to continue with the rest of the tutorial as the code examples in the other lessons are executable in-browser. + +## Install .NET Core + +If you haven't already, you will first need to install .NET Core on your machine. Go to the [.NET Core Page](https://www.microsoft.com/net/core) of the Microsoft website, and follow the installation instructions for your platform of choice. You can ensure .NET Core is installed by running the following command: + +``` +dotnet --version +``` + +## Create New Project + +Create a new project by running the following commands (you can skip these steps if you want to add EF Core to an existing project): + +``` +mkdir MyEfCoreProject # Create directory for project +cd MyEfCoreProject # Navigate to project directory +dotnet new # Initialize .NET Core project (generates Startup.cs and project.json) +``` + +## Add EF Core to Project + +To add EF Core to your project, you need to list it as a dependency in your `project.json` file. You need to add the appropriate package for your database provider as well. See [Database Providers](https://docs.efproject.net/en/latest/providers/index.html) in the docs for a full listing of available database providers. In this example, we use Sqlite. + +```json +"dependencies": + "Microsoft.EntityFrameworkCore.Sqlite": "1.0.0", + "Microsoft.EntityFrameworkCore.Design": { + "version": "1.0.0-preview2-final", + "type": "build" + } +} +``` + +To add EF Core functionality to the [.NET Core Command-Line Interface](https://docs.microsoft.com/en-us/dotnet/articles/core/tools/), you need to add a package to the `tools` section of `project.json`: + +``` +"tools": { + "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final" +} +``` + +Once you have updated `package.json`, run the following command to install your project's tools and dependencies: + +``` +dotnet restore +``` + +After running this command, EF Core should be installed on your machine. You can run the following command to ensure EF Core was installed correctly: + +``` +dotnet ef --help +``` + diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index 1041165..f75ec13 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -1 +1,2 @@ -- [Intro to EF Core](what-is-ef-core.md) \ No newline at end of file +- [Intro to EF Core](intro-to-ef-core.md) +- [Installing EF Core](installing-ef-core.md) \ No newline at end of file From 1851ab938f22d42eba0b26c3094037e7ab256c83 Mon Sep 17 00:00:00 2001 From: arynhuck Date: Tue, 8 Nov 2016 16:26:25 -0600 Subject: [PATCH 14/56] Resolves #22 - Supported Database Providers Discusses supported database providers on the Intro to EF Core page. --- content/efcore/getting-started/intro-to-ef-core.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/content/efcore/getting-started/intro-to-ef-core.md b/content/efcore/getting-started/intro-to-ef-core.md index 6636216..d52f84c 100644 --- a/content/efcore/getting-started/intro-to-ef-core.md +++ b/content/efcore/getting-started/intro-to-ef-core.md @@ -2,4 +2,8 @@ Entity Framework Core (EF Core) is a lightweight, extensible, and cross-platform version of Entity Framework. Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects. This allows developers to create and manage databases without most of the data-access code that developers usually need to write.  -EF Core and the latest version of Entity Framework (EF6.x) differ in the features they support. A comparison of the features supported by each can be found on the [feature comparison page](https://docs.efproject.net/en/latest/efcore-vs-ef6/features.html) of the docs. If you want help determining which version is best for your project, check out the ["Which One Is Right for You?"](https://docs.efproject.net/en/latest/efcore-vs-ef6/choosing.html) page. \ No newline at end of file +EF Core and the latest version of Entity Framework (EF6.x) differ in the features they support. A comparison of the features supported by each can be found on the [feature comparison page](https://docs.efproject.net/en/latest/efcore-vs-ef6/features.html) of the docs. If you want help determining which version is best for your project, check out the ["Which One Is Right for You?"](https://docs.efproject.net/en/latest/efcore-vs-ef6/choosing.html) page. + +## Database Providers + +At the moment, EF Core only supports relational databases, but there are plans to add support for non-relational databases in the future. Supported database providers are listed on the [Database Providers page](https://docs.efproject.net/en/latest/providers/index.html) in the docs. \ No newline at end of file From 67473897f590740b411932e6ac49bc7683f49573 Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Tue, 8 Nov 2016 20:02:12 -0600 Subject: [PATCH 15/56] Resolves #3 - Querying Data Lesson --- content/efcore/getting-started/README.md | 4 +- content/efcore/getting-started/querying.md | 89 +++++++++++++++++++ .../samples/filtering-entities/Program.cs | 21 +++++ .../samples/filtering-entities/README.md | 9 ++ .../samples/loading-all-entities/Program.cs | 18 ++++ .../samples/loading-all-entities/README.md | 9 ++ .../samples/loading-single-entity/Program.cs | 16 ++++ .../samples/loading-single-entity/README.md | 9 ++ .../getting-started/samples/shared/Author.cs | 6 ++ .../getting-started/samples/shared/Book.cs | 9 ++ .../samples/shared/LibraryContext.cs | 13 +++ content/efcore/getting-started/toc.md | 3 +- 12 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 content/efcore/getting-started/querying.md create mode 100644 content/efcore/getting-started/samples/filtering-entities/Program.cs create mode 100644 content/efcore/getting-started/samples/filtering-entities/README.md create mode 100644 content/efcore/getting-started/samples/loading-all-entities/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-all-entities/README.md create mode 100644 content/efcore/getting-started/samples/loading-single-entity/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-single-entity/README.md create mode 100644 content/efcore/getting-started/samples/shared/Author.cs create mode 100644 content/efcore/getting-started/samples/shared/Book.cs create mode 100644 content/efcore/getting-started/samples/shared/LibraryContext.cs diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 9b1953d..5d928e7 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -12,5 +12,7 @@ This tutorial is aimed at people who are learning EF Core for the first time. Mo ## Topics Covered This tutorial will cover the following topics: + - [Intro to EF Core](intro-to-ef-core.md) -- [Installing EF Core](installing-ef-core.md) \ No newline at end of file +- [Installing EF Core](installing-ef-core.md) +- [Querying Data](querying.md) diff --git a/content/efcore/getting-started/querying.md b/content/efcore/getting-started/querying.md new file mode 100644 index 0000000..eee5cdf --- /dev/null +++ b/content/efcore/getting-started/querying.md @@ -0,0 +1,89 @@ +# Querying Data + +In this lesson, you'll learn how to use querying to fetch one or more items from your database. EF Core uses LINQ to query data, so it is important that you understand LINQ before going through this lesson. Check out the [LINQ lesson](../../csharp/getting-started/linq.md) in the C# Interactive Tutorial if you need a refresher. + +## Example database + +For this lesson, we will use a small database to allow you to try querying on your own. The database has two tables, Books and Authors, and the data is as follows: + +### Books +| BookId | AuthorId | Title | Genre | PublicationYear | +|--------|----------|---------------------------------|------------------|-----------------| +| 1 | 9 | Mrs. Dalloway | Literary | 1925 | +| 2 | 6 | The Mysterious Island | Science Fiction | 1874 | +| 3 | 7 | The Blazing World | Science Fiction | 1666 | +| 4 | 1 | The Scarlet Plague | Science Fiction | 1912 | +| 5 | 8 | The Secret Adversary | Mystery | 1922 | +| 6 | 6 | An Antarctic Mystery | Mystery | 1897 | +| 7 | 5 | My Bondage and My Freedom | Narrative | 1855 | +| 8 | 3 | The Count of Monte Cristo | Adventure | 1845 | +| 9 | 10 | Minnie's Sacrifice | Historical | 1869 | +| 10 | 4 | My Antonia | Historical | 1918 | +| 11 | 4 | O Pioneers! | Historical | 1913 | +| 12 | 2 | Adventures of Huckleberry Finn | Satire | 1884 | +| 13 | 2 | The Adventures of Tom Sawyer | Satire | 1876 | +| 14 | 10 | Iola Leroy | Historical | 1892 | +| 15 | 8 | Murder on the Orient Express | Mystery | 1934 | +| 16 | 1 | The Call of the Wild | Adventure | 1903 | +| 17 | 4 | Death Comes for the Archbishop | Historical | 1927 | + +### Authors +| AuthorId | FirstName | LastName | +|----------|------------|-----------| +| 1 | Jack | London | +| 2 | Mark | Twain | +| 3 | Alexandre | Dumas | +| 4 | Willa | Cather | +| 5 | Frederick | Douglass | +| 6 | Jules | Vern | +| 7 | Margaret | Cavendish | +| 8 | Agatha | Christie | +| 9 | Virginia | Woolf | +| 10 | Frances | Harper | +| 11 | Stephen | Crane | + +## Loading All Entities + +Let's say we want to get all of the books from our database in a C# application. Normally, we would have to write a database query in a domain-specific language, such as SQL, and then we would have to manually map the results of this query to C# objects. With EF Core, this process is much easier because it takes care of the data access code for us. + +```c# +using (var context = new LibraryContext()) +{ + var books = context.Books.ToList(); +} +``` + +In order to interact with the database via EF Core, we must first create an instance of our context (`LibraryContext`). Notice that we create the context with the `using` keyword. This automatically disposes the context after the using block has finished executing. Alternatively, we could manually call `LibraryContext.dispose()`, but the `using` method is more convenient and readable. It is imperative that we dispose of the context after we are finished using it because it holds an open connection to the database. + +Once we have an instance of the context, we can use it to interact with the database. To access the books in the database, we reference the relevant `DbSet` within the context - `Books` in our case - and call the `ToList` method to convert the `DbSet` to a `List`. The resulting list will contain all of the books within the database. + +## Filtering Entities + +Loading all of the entities from a database is useful, but there are many use cases where we only want to load a subset of the entities from the database. For example, we may want to filter books by author or genre. EF Core allows us to filter entities via the `Where` extension method. Let's look at an example where we retrieve all science fiction books from the database. + +```c# +using (var context = new LibraryContext()) +{ + var books = context.Books + .Where(b => b.Genre == "Science Fiction") + .ToList(); +} +``` + +We use a lambda expression within the `Where` method to detect if the `Genre` property of each book is equal to "Science Fiction". Books that meet the criteria of the lambda expression will be included in the final result, while books that do not will be excluded. + +We could retrieve all of the books like in the previous example and then filter them in our application; however, this would require us to load all of the books into memory, and it does not allow us to take advantage of our database's optimized querying functionality. Allowing the database to do what it does best and perform the filtering for us results in a significant performance increase. Thus, it is important that we filter the `DbSet` with the `Where` method before calling `ToList`. + +## Loading a Single Entity + +Both of our examples so far have shown how to retrieve a collection of entities. Let's look at how to retrieve a single entity based on a unique identifier. + +```c# +using (var context = new LibraryContext()) +{ + var book = context.Books + .Single(b => b.Id == 1); +} +``` + +In this example, we use the `Single` extension method to find the book with an `Id` of 1. Note that we do not need to call `ToList()` because `Single` returns a single entity. It is important to only use `Single` with unique identifiers because if multiple entities meet the success criteria a `System.InvalidOperationException` will be thrown. \ No newline at end of file diff --git a/content/efcore/getting-started/samples/filtering-entities/Program.cs b/content/efcore/getting-started/samples/filtering-entities/Program.cs new file mode 100644 index 0000000..1750d01 --- /dev/null +++ b/content/efcore/getting-started/samples/filtering-entities/Program.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var books = context.Books + .Where(s => s.Genre.Contains("Science Fiction")) + .ToList(); + + foreach (Book book in books) + { + Console.WriteLine(String.Format("{0} - {1}", book.Title, book.Genre)); + } + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/filtering-entities/README.md b/content/efcore/getting-started/samples/filtering-entities/README.md new file mode 100644 index 0000000..2cefbae --- /dev/null +++ b/content/efcore/getting-started/samples/filtering-entities/README.md @@ -0,0 +1,9 @@ +# Filtering Entities + +This code example demonstrates how to use EF Core to query a subset of entities from the database based on specified filters. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) +- [Book.cs](../shared/Book.cs) +- [Author.cs](../shared/Author.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-all-entities/Program.cs b/content/efcore/getting-started/samples/loading-all-entities/Program.cs new file mode 100644 index 0000000..3106389 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-all-entities/Program.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var books = context.Books.ToList(); + foreach (Book book in books) + { + Console.WriteLine(book.Title); + } + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-all-entities/README.md b/content/efcore/getting-started/samples/loading-all-entities/README.md new file mode 100644 index 0000000..35b8f2b --- /dev/null +++ b/content/efcore/getting-started/samples/loading-all-entities/README.md @@ -0,0 +1,9 @@ +# Loading All Entities + +This code example demonstrates how to use EF Core to query all entities from the database. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) +- [Book.cs](../shared/Book.cs) +- [Author.cs](../shared/Author.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-single-entity/Program.cs b/content/efcore/getting-started/samples/loading-single-entity/Program.cs new file mode 100644 index 0000000..87f69cc --- /dev/null +++ b/content/efcore/getting-started/samples/loading-single-entity/Program.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var book = context.Books + .Single(s => s.BookId == 1); + Console.WriteLine(book.Title); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-single-entity/README.md b/content/efcore/getting-started/samples/loading-single-entity/README.md new file mode 100644 index 0000000..59c4aa7 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-single-entity/README.md @@ -0,0 +1,9 @@ +# Loading A Single Entity + +This code example demonstrates how to use EF Core to query a single entity from the database. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) +- [Book.cs](../shared/Book.cs) +- [Author.cs](../shared/Author.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/Author.cs b/content/efcore/getting-started/samples/shared/Author.cs new file mode 100644 index 0000000..8bd1c6a --- /dev/null +++ b/content/efcore/getting-started/samples/shared/Author.cs @@ -0,0 +1,6 @@ +public class Author +{ + public int AuthorId { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/Book.cs b/content/efcore/getting-started/samples/shared/Book.cs new file mode 100644 index 0000000..01e5070 --- /dev/null +++ b/content/efcore/getting-started/samples/shared/Book.cs @@ -0,0 +1,9 @@ +public class Book +{ + public int BookId { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } + + public Author Author { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/LibraryContext.cs b/content/efcore/getting-started/samples/shared/LibraryContext.cs new file mode 100644 index 0000000..236a464 --- /dev/null +++ b/content/efcore/getting-started/samples/shared/LibraryContext.cs @@ -0,0 +1,13 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; + +public class LibraryContext : DbContext +{ + public DbSet Books { get; set; } + public DbSet Authors { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite("Filename=Library.db"); + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index f75ec13..117193c 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -1,2 +1,3 @@ - [Intro to EF Core](intro-to-ef-core.md) -- [Installing EF Core](installing-ef-core.md) \ No newline at end of file +- [Installing EF Core](installing-ef-core.md) +- [Querying Data](querying.md) \ No newline at end of file From 2ddb531fac56e18d7f0082620cf7d8496806239b Mon Sep 17 00:00:00 2001 From: arynhuck Date: Tue, 22 Nov 2016 17:18:04 -0600 Subject: [PATCH 16/56] Resolves #27 - fixes broken links Updated links from doc.efproject.net to docs.microsoft.com --- content/efcore/getting-started/README.md | 2 +- content/efcore/getting-started/installing-ef-core.md | 2 +- content/efcore/getting-started/intro-to-ef-core.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 5d928e7..7a94e34 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -2,7 +2,7 @@ ## Who Should Read This? -This tutorial is aimed at people who are learning EF Core for the first time. More advanced functionality is covered in the [docs](https://docs.efproject.net/en/latest/). Before beginning this tutorial, you should understand the following topics: +This tutorial is aimed at people who are learning EF Core for the first time. More advanced functionality is covered in the [docs](https://docs.microsoft.com/en-us/ef/). Before beginning this tutorial, you should understand the following topics: - C# (see [Getting Started with C#](https://www.microsoft.com/net/tutorials/csharp/getting-started)) - Relational database concepts diff --git a/content/efcore/getting-started/installing-ef-core.md b/content/efcore/getting-started/installing-ef-core.md index 5655e36..f59da77 100644 --- a/content/efcore/getting-started/installing-ef-core.md +++ b/content/efcore/getting-started/installing-ef-core.md @@ -22,7 +22,7 @@ dotnet new # Initialize .NET Core project (generates Startup.cs and p ## Add EF Core to Project -To add EF Core to your project, you need to list it as a dependency in your `project.json` file. You need to add the appropriate package for your database provider as well. See [Database Providers](https://docs.efproject.net/en/latest/providers/index.html) in the docs for a full listing of available database providers. In this example, we use Sqlite. +To add EF Core to your project, you need to list it as a dependency in your `project.json` file. You need to add the appropriate package for your database provider as well. See [Database Providers](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs for a full listing of available database providers. In this example, we use Sqlite. ```json "dependencies": diff --git a/content/efcore/getting-started/intro-to-ef-core.md b/content/efcore/getting-started/intro-to-ef-core.md index d52f84c..510c446 100644 --- a/content/efcore/getting-started/intro-to-ef-core.md +++ b/content/efcore/getting-started/intro-to-ef-core.md @@ -2,8 +2,8 @@ Entity Framework Core (EF Core) is a lightweight, extensible, and cross-platform version of Entity Framework. Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects. This allows developers to create and manage databases without most of the data-access code that developers usually need to write.  -EF Core and the latest version of Entity Framework (EF6.x) differ in the features they support. A comparison of the features supported by each can be found on the [feature comparison page](https://docs.efproject.net/en/latest/efcore-vs-ef6/features.html) of the docs. If you want help determining which version is best for your project, check out the ["Which One Is Right for You?"](https://docs.efproject.net/en/latest/efcore-vs-ef6/choosing.html) page. +EF Core and the latest version of Entity Framework (EF6.x) differ in the features they support. A comparison of the features supported by each can be found on the [feature comparison page](https://docs.microsoft.com/en-us/ef/efcore-and-ef6/features) of the docs. If you want help determining which version is best for your project, check out the ["Which One Is Right for You?"](https://docs.microsoft.com/en-us/ef/efcore-and-ef6/choosing) page. ## Database Providers -At the moment, EF Core only supports relational databases, but there are plans to add support for non-relational databases in the future. Supported database providers are listed on the [Database Providers page](https://docs.efproject.net/en/latest/providers/index.html) in the docs. \ No newline at end of file +At the moment, EF Core only supports relational databases, but there are plans to add support for non-relational databases in the future. Supported database providers are listed on the [Database Providers page](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs. From ddfce97a12f69e0a8eb11e1ff5df0cfdbd841671 Mon Sep 17 00:00:00 2001 From: deakgeek Date: Tue, 29 Nov 2016 17:40:57 -0600 Subject: [PATCH 17/56] Resolves #29 - Change Query Tutorial Genre --- content/efcore/getting-started/querying.md | 6 +++--- .../getting-started/samples/filtering-entities/Program.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/efcore/getting-started/querying.md b/content/efcore/getting-started/querying.md index eee5cdf..4647caa 100644 --- a/content/efcore/getting-started/querying.md +++ b/content/efcore/getting-started/querying.md @@ -59,18 +59,18 @@ Once we have an instance of the context, we can use it to interact with the data ## Filtering Entities -Loading all of the entities from a database is useful, but there are many use cases where we only want to load a subset of the entities from the database. For example, we may want to filter books by author or genre. EF Core allows us to filter entities via the `Where` extension method. Let's look at an example where we retrieve all science fiction books from the database. +Loading all of the entities from a database is useful, but there are many use cases where we only want to load a subset of the entities from the database. For example, we may want to filter books by author or genre. EF Core allows us to filter entities via the `Where` extension method. Let's look at an example where we retrieve all Historical books from the database. ```c# using (var context = new LibraryContext()) { var books = context.Books - .Where(b => b.Genre == "Science Fiction") + .Where(b => b.Genre == "Historical") .ToList(); } ``` -We use a lambda expression within the `Where` method to detect if the `Genre` property of each book is equal to "Science Fiction". Books that meet the criteria of the lambda expression will be included in the final result, while books that do not will be excluded. +We use a lambda expression within the `Where` method to detect if the `Genre` property of each book is equal to "Historical". Books that meet the criteria of the lambda expression will be included in the final result, while books that do not will be excluded. We could retrieve all of the books like in the previous example and then filter them in our application; however, this would require us to load all of the books into memory, and it does not allow us to take advantage of our database's optimized querying functionality. Allowing the database to do what it does best and perform the filtering for us results in a significant performance increase. Thus, it is important that we filter the `DbSet` with the `Where` method before calling `ToList`. diff --git a/content/efcore/getting-started/samples/filtering-entities/Program.cs b/content/efcore/getting-started/samples/filtering-entities/Program.cs index 1750d01..1e05ed9 100644 --- a/content/efcore/getting-started/samples/filtering-entities/Program.cs +++ b/content/efcore/getting-started/samples/filtering-entities/Program.cs @@ -9,7 +9,7 @@ public static void Main() using (var context = new LibraryContext()) { var books = context.Books - .Where(s => s.Genre.Contains("Science Fiction")) + .Where(b => b.Genre == "Historical") .ToList(); foreach (Book book in books) From 0c036fd06148805239367302afcc991063580e46 Mon Sep 17 00:00:00 2001 From: deakgeek Date: Tue, 6 Dec 2016 16:59:22 -0600 Subject: [PATCH 18/56] Resolves #35 Updates loading single entity example to use letter b instead of s --- .../getting-started/samples/loading-single-entity/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/efcore/getting-started/samples/loading-single-entity/Program.cs b/content/efcore/getting-started/samples/loading-single-entity/Program.cs index 87f69cc..c0a1c52 100644 --- a/content/efcore/getting-started/samples/loading-single-entity/Program.cs +++ b/content/efcore/getting-started/samples/loading-single-entity/Program.cs @@ -9,7 +9,7 @@ public static void Main() using (var context = new LibraryContext()) { var book = context.Books - .Single(s => s.BookId == 1); + .Single(b => b.BookId == 1); Console.WriteLine(book.Title); } } From 616777a0c994ba7081041a2953a49611d267414a Mon Sep 17 00:00:00 2001 From: deakgeek Date: Tue, 6 Dec 2016 18:25:03 -0600 Subject: [PATCH 19/56] Resolves #34 - Update LibraryContext.cs to use DBHelper --- .../efcore/getting-started/samples/shared/LibraryContext.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/efcore/getting-started/samples/shared/LibraryContext.cs b/content/efcore/getting-started/samples/shared/LibraryContext.cs index 236a464..4c169bf 100644 --- a/content/efcore/getting-started/samples/shared/LibraryContext.cs +++ b/content/efcore/getting-started/samples/shared/LibraryContext.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using System.Collections.Generic; +using REPLHelper; public class LibraryContext : DbContext { @@ -8,6 +9,6 @@ public class LibraryContext : DbContext protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseSqlite("Filename=Library.db"); + optionsBuilder.UseSqlite(DBHelper.GetReadonlyDbConnectionString()); } } \ No newline at end of file From 1240ac6d5a8441f02e0a1757db892dd658fc0cbb Mon Sep 17 00:00:00 2001 From: Ryan Helmoski Date: Wed, 7 Dec 2016 14:38:30 -0600 Subject: [PATCH 20/56] Resolves #41 - missing brace (#43) --- content/efcore/getting-started/installing-ef-core.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/efcore/getting-started/installing-ef-core.md b/content/efcore/getting-started/installing-ef-core.md index f59da77..2e90330 100644 --- a/content/efcore/getting-started/installing-ef-core.md +++ b/content/efcore/getting-started/installing-ef-core.md @@ -24,8 +24,8 @@ dotnet new # Initialize .NET Core project (generates Startup.cs and p To add EF Core to your project, you need to list it as a dependency in your `project.json` file. You need to add the appropriate package for your database provider as well. See [Database Providers](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs for a full listing of available database providers. In this example, we use Sqlite. -```json -"dependencies": +```{json} +"dependencies": { "Microsoft.EntityFrameworkCore.Sqlite": "1.0.0", "Microsoft.EntityFrameworkCore.Design": { "version": "1.0.0-preview2-final", From d3dc8118a0e8821492bac490b1bfc66ea34d68bf Mon Sep 17 00:00:00 2001 From: Ryan Helmoski Date: Thu, 8 Dec 2016 15:37:17 -0600 Subject: [PATCH 21/56] Resolves #39 - updates tutorials to support multiple files --- content/efcore/getting-started/querying.md | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/content/efcore/getting-started/querying.md b/content/efcore/getting-started/querying.md index 4647caa..63295b5 100644 --- a/content/efcore/getting-started/querying.md +++ b/content/efcore/getting-started/querying.md @@ -26,7 +26,8 @@ For this lesson, we will use a small database to allow you to try querying on yo | 15 | 8 | Murder on the Orient Express | Mystery | 1934 | | 16 | 1 | The Call of the Wild | Adventure | 1903 | | 17 | 4 | Death Comes for the Archbishop | Historical | 1927 | - + + ### Authors | AuthorId | FirstName | LastName | |----------|------------|-----------| @@ -46,12 +47,14 @@ For this lesson, we will use a small database to allow you to try querying on yo Let's say we want to get all of the books from our database in a C# application. Normally, we would have to write a database query in a domain-specific language, such as SQL, and then we would have to manually map the results of this query to C# objects. With EF Core, this process is much easier because it takes care of the data access code for us. -```c# +```{.snippet} using (var context = new LibraryContext()) { var books = context.Books.ToList(); } -``` +``` +:::repl{data-name=loading-all-entities} +::: In order to interact with the database via EF Core, we must first create an instance of our context (`LibraryContext`). Notice that we create the context with the `using` keyword. This automatically disposes the context after the using block has finished executing. Alternatively, we could manually call `LibraryContext.dispose()`, but the `using` method is more convenient and readable. It is imperative that we dispose of the context after we are finished using it because it holds an open connection to the database. @@ -61,14 +64,16 @@ Once we have an instance of the context, we can use it to interact with the data Loading all of the entities from a database is useful, but there are many use cases where we only want to load a subset of the entities from the database. For example, we may want to filter books by author or genre. EF Core allows us to filter entities via the `Where` extension method. Let's look at an example where we retrieve all Historical books from the database. -```c# +```{.snippet} using (var context = new LibraryContext()) { var books = context.Books .Where(b => b.Genre == "Historical") .ToList(); } -``` +``` +:::repl{data-name=filtering-entities} +::: We use a lambda expression within the `Where` method to detect if the `Genre` property of each book is equal to "Historical". Books that meet the criteria of the lambda expression will be included in the final result, while books that do not will be excluded. @@ -78,12 +83,14 @@ We could retrieve all of the books like in the previous example and then filter Both of our examples so far have shown how to retrieve a collection of entities. Let's look at how to retrieve a single entity based on a unique identifier. -```c# +```{.snippet} using (var context = new LibraryContext()) { var book = context.Books .Single(b => b.Id == 1); } -``` +``` +:::repl{data-name=loading-single-entity} +::: -In this example, we use the `Single` extension method to find the book with an `Id` of 1. Note that we do not need to call `ToList()` because `Single` returns a single entity. It is important to only use `Single` with unique identifiers because if multiple entities meet the success criteria a `System.InvalidOperationException` will be thrown. \ No newline at end of file +In this example, we use the `Single` extension method to find the book with an `Id` of 1. Note that we do not need to call `ToList()` because `Single` returns a single entity. It is important to only use `Single` with unique identifiers because if multiple entities meet the success criteria a `System.InvalidOperationException` will be thrown. From 80f76cb38f6a13655893da1e5dec3c2632ea1b67 Mon Sep 17 00:00:00 2001 From: arynhuck Date: Thu, 8 Dec 2016 16:07:36 -0600 Subject: [PATCH 22/56] Resolves #44 - Describe context in querying tutorial --- content/efcore/getting-started/querying.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/efcore/getting-started/querying.md b/content/efcore/getting-started/querying.md index 63295b5..df06839 100644 --- a/content/efcore/getting-started/querying.md +++ b/content/efcore/getting-started/querying.md @@ -56,7 +56,9 @@ using (var context = new LibraryContext()) :::repl{data-name=loading-all-entities} ::: -In order to interact with the database via EF Core, we must first create an instance of our context (`LibraryContext`). Notice that we create the context with the `using` keyword. This automatically disposes the context after the using block has finished executing. Alternatively, we could manually call `LibraryContext.dispose()`, but the `using` method is more convenient and readable. It is imperative that we dispose of the context after we are finished using it because it holds an open connection to the database. +In order to interact with the database via EF Core, we must first create an instance of our context (`LibraryContext`). `LibraryContext` extends EF Core's [`DbContext`](https://msdn.microsoft.com/library/system.data.entity.dbcontext) class which manages entity objects during runtime, and allows us to perform common database operations like running queries. + +Notice that we create the context with the `using` keyword. This automatically disposes the context after the using block has finished executing. Alternatively, we could manually call `LibraryContext.dispose()`, but the `using` method is more convenient and readable. It is imperative that we dispose of the context after we are finished using it because it holds an open connection to the database. Once we have an instance of the context, we can use it to interact with the database. To access the books in the database, we reference the relevant `DbSet` within the context - `Books` in our case - and call the `ToList` method to convert the `DbSet` to a `List`. The resulting list will contain all of the books within the database. From bdfd22aa0785dfde98f8a955d7fb4c1e19f97adb Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Sat, 10 Dec 2016 00:48:55 -0600 Subject: [PATCH 23/56] Resolves #51 - standardize target audience header removes question mark on who should read this header --- content/efcore/getting-started/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 7a94e34..3ba7914 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -1,6 +1,6 @@ # Getting Started with Entity Framework Core -## Who Should Read This? +## Who Should Read This This tutorial is aimed at people who are learning EF Core for the first time. More advanced functionality is covered in the [docs](https://docs.microsoft.com/en-us/ef/). Before beginning this tutorial, you should understand the following topics: From 21198418ee795bcef9fdca671e021e4203ffc9dc Mon Sep 17 00:00:00 2001 From: deakgeek Date: Sun, 11 Dec 2016 22:47:28 -0600 Subject: [PATCH 24/56] Resolves #6 - loading related data --- content/efcore/getting-started/README.md | 1 + .../getting-started/loading-related-data.md | 173 ++++++++++++++++++ .../samples/filtering-entities/README.md | 9 - .../samples/loading-all-entities/README.md | 9 - .../count-method/Program.cs | 21 +++ .../count-method/README.md | 11 ++ .../field-not-included/Program.cs | 17 ++ .../field-not-included/README.md | 11 ++ .../Program.cs | 25 +++ .../README.md | 11 ++ .../include-method/Program.cs | 18 ++ .../include-method/README.md | 11 ++ .../load-method/Program.cs | 23 +++ .../load-method/README.md | 11 ++ .../min-method/Program.cs | 22 +++ .../loading-related-data/min-method/README.md | 11 ++ .../multiple-include-methods/Program.cs | 22 +++ .../multiple-include-methods/README.md | 11 ++ .../query-method/Program.cs | 26 +++ .../query-method/README.md | 11 ++ .../then-include-method-chain/Program.cs | 26 +++ .../then-include-method-chain/README.md | 11 ++ .../then-include-method/Program.cs | 22 +++ .../then-include-method/README.md | 11 ++ .../samples/loading-single-entity/README.md | 9 - .../filtering-entities/Program.cs | 0 .../querying/filtering-entities/README.md | 11 ++ .../loading-all-entities/Program.cs | 0 .../querying/loading-all-entities/README.md | 11 ++ .../loading-single-entity/Program.cs | 0 .../querying/loading-single-entity/README.md | 11 ++ .../getting-started/samples/shared/Author.cs | 3 + .../getting-started/samples/shared/Book.cs | 4 +- .../getting-started/samples/shared/Edition.cs | 7 + .../samples/shared/LibraryContext.cs | 3 +- .../samples/shared/Publisher.cs | 8 + content/efcore/getting-started/toc.md | 3 +- .../tutorial-database-reference.md | 64 +++++++ .../tutorial-model-reference.md | 55 ++++++ 39 files changed, 683 insertions(+), 30 deletions(-) create mode 100644 content/efcore/getting-started/loading-related-data.md delete mode 100644 content/efcore/getting-started/samples/filtering-entities/README.md delete mode 100644 content/efcore/getting-started/samples/loading-all-entities/README.md create mode 100644 content/efcore/getting-started/samples/loading-related-data/count-method/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-related-data/count-method/README.md create mode 100644 content/efcore/getting-started/samples/loading-related-data/field-not-included/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md create mode 100644 content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md create mode 100644 content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-related-data/include-method/README.md create mode 100644 content/efcore/getting-started/samples/loading-related-data/load-method/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-related-data/load-method/README.md create mode 100644 content/efcore/getting-started/samples/loading-related-data/min-method/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-related-data/min-method/README.md create mode 100644 content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md create mode 100644 content/efcore/getting-started/samples/loading-related-data/query-method/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-related-data/query-method/README.md create mode 100644 content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md create mode 100644 content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs create mode 100644 content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md delete mode 100644 content/efcore/getting-started/samples/loading-single-entity/README.md rename content/efcore/getting-started/samples/{ => querying}/filtering-entities/Program.cs (100%) create mode 100644 content/efcore/getting-started/samples/querying/filtering-entities/README.md rename content/efcore/getting-started/samples/{ => querying}/loading-all-entities/Program.cs (100%) create mode 100644 content/efcore/getting-started/samples/querying/loading-all-entities/README.md rename content/efcore/getting-started/samples/{ => querying}/loading-single-entity/Program.cs (100%) create mode 100644 content/efcore/getting-started/samples/querying/loading-single-entity/README.md create mode 100644 content/efcore/getting-started/samples/shared/Edition.cs create mode 100644 content/efcore/getting-started/samples/shared/Publisher.cs create mode 100644 content/efcore/getting-started/tutorial-database-reference.md create mode 100644 content/efcore/getting-started/tutorial-model-reference.md diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 3ba7914..9c1c457 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -16,3 +16,4 @@ This tutorial will cover the following topics: - [Intro to EF Core](intro-to-ef-core.md) - [Installing EF Core](installing-ef-core.md) - [Querying Data](querying.md) +- [Loading Related Data] (loading-related-data.md) diff --git a/content/efcore/getting-started/loading-related-data.md b/content/efcore/getting-started/loading-related-data.md new file mode 100644 index 0000000..d576628 --- /dev/null +++ b/content/efcore/getting-started/loading-related-data.md @@ -0,0 +1,173 @@ +# Loading Related Data + +> **Note** {.note} +> If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](database-reference.md) and [Model Reference](model-reference) pages. + +## Single Layer Inclusion + +When loading an entity from the database, EF Core will automatically include properties that are primitive types, but non-primitive types (such as other entities) won't be included. For example, if you run the following code snippet, you will see that the `Author` field is `null`: + +```{.snippet} +using (var context = new LibraryContext()) +{ + var book = context.Books + .Single(b => b.BookId == 1); +} +``` +:::repl{data-name=field-not-included} +::: + +We need to explicitly tell EF Core if we want to load a non-primitive type like the Author field. We do this using the `Include` method. In the example below, the book that is returned will include its author's information. + +```{.snippet} +using (var context = new LibraryContext()) +{ + var book = context.Books + .Include(b => b.Author) + .Single(b => b.BookId == 1); +} +``` +:::repl{data-name=include-method} +::: + +You can also include multiple non-primitive type properties at once by calling the `Include` method multiple times. For example, we can include the `Editions` and `Authors` properties of the `Book` entity like so: + +```{.snippet} +using (var context = new LibraryContext()) +{ + var book = context.Books + .Include(b => b.Editions) + .Include(b => b.Author) + .Single(b => b.BookId == 1); +} +``` +:::repl{data-name=multiple-include-methods} +::: + +## Multi-layer Inclusion + +Now, what happens if one of the properties we include also has non-primitive type properties? By default, they won't be loaded from the database, but we can tell EF Core to load them using the `ThenInclude` method. For example, we can load the publisher information for the editions of a book like so: + +```{.snippet} +using (var context = new LibraryContext()) +{ + var book = context.Book + .Include(b => b.Editions) + .ThenInclude(e => e.Publisher) + .Single(b => b.BookId == 1) ; +} +``` +:::repl{data-name=then-include-method} +::: + +We can also chain `ThenInclude` calls to include deeper layers of related data. For example, if we want to find out the publisher information for the different editions of Fredrick Douglass' books in this library, we will need to chain `ThenInclude` calls to get the book, edition, and publisher information. + +```{.snippet} +using (var context = new LibraryContext()) +{ + var author = context.Authors + .Include(a => a.Books) + .ThenInclude(b => b.Editions) + .ThenInclude(e => e.Publisher) + .Single(a => a.LastName == "Douglass"); +} +``` +:::repl{data-name=then-include-method-chain} +::: + +A mix of `Include` and `ThenInclude` commands can also be chained together to include related data from multiple layers across related entities. In the following example, we are looking for the author, editions, and edition publishers of _The Call of the Wild_. + +```{.snippet} +using (var context = new LibraryContext()) +{ + var book = context.Books + .Include(b => b.Editions) + .ThenInclude(e => e.Publisher) + .Include(b => b.Author) + .Single(b => b.Title.Contains("Call of the Wild")); +} +``` +:::repl{data-name=include-and-then-include-method-chain} +::: + +## Explicit Loading + +> **Note** {.note} +> Explicit Loading support was introduced in EF Core 1.1.0. If you are using an earlier release, the functionality in this section will not be available. + +In the previous section, we used *eager loading* which loads the related data from the database as part of the initial database query. Another option is to use *explicit loading* which retrieves the related data separately from the original database query. This allows us to query and filter the related entities before loading them into memory, so we only pull the necessary information from the database. + +To use explicit loading, we first use the context's `Entry` method to specify the entity that we want to load related data for. Then, we use the `Collection` and `Reference` methods to specify the related data to load for the entity. `Collection` is used when retrieving multiple items, and `Reference` is used for single items. Finally, we use the `Load` method to actually load the data from the database. + +In the following example, we first eagerly load the author, Mark Twain. Then, we explicitly load his books. This means the books will be loaded in a separate database query after the initial author query. + +```{.snippet} +using (var context = new LibraryContext()) +{ + var author = context.Authors + .Single(a => a.LastName == "Twain"); + + context.Entry(author) + .Collection(a => a.Books) + .Load(); +} +``` +:::repl{data-name=load-method} +::: + +In the above example, we returned all of Twain's books, but what if we only wanted to load a specific book of Twain's, say _Adventures of Huckleberry Finn_? We would use the `Query` command to search for it. + +```{.snippet} +using (var context = new LibraryContext()) +{ + var author = context.Authors + .Single(a => a.LastName == "Twain"); + + context.Entry(author) + .Collection(a => a.Books) + .Query() + .Where(b => b.Title.Contains("Huck")) + .Load(); +} +``` +:::repl{data-name=query-method} +::: + +By using explicit loading, we were able to load only the book we want (_Adventures of Huckleberry Finn_). If we had used eager loading, we would have loaded all of Twain's books. + +### Aggregate Functions + +When using explicit loading, we can also use aggregate functions, such as count, max, min, and sum, which allow us to perform calculations on the data without loading it all into memory. The following example counts how many books in the library are by Willa Cather without having to load all of the books into memory: + +```{.snippet} +using (var context = new LibraryContext()) +{ + var author = context.Authors + .Single(a => a.LastName == "Cather"); + + var numBooks = context.Entry(author) + .Collection(a => a.Books) + .Query() + .Count(); +} +``` +:::repl{data-name=count-method} +::: + +Likewise, we can find the year of the oldest edition of a book using the `Min` method: + +```{.snippet} +using (var context = new LibraryContext()) +{ + var book = context.Books + .Single(b => b.Title == "The Scarlet Plague"); + + var year = context.Entry(book) + .Collection(b => b.Editions) + .Query() + .Min(e => e.Year); +} +``` +:::repl{data-name=min-method} +::: + \ No newline at end of file diff --git a/content/efcore/getting-started/samples/filtering-entities/README.md b/content/efcore/getting-started/samples/filtering-entities/README.md deleted file mode 100644 index 2cefbae..0000000 --- a/content/efcore/getting-started/samples/filtering-entities/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Filtering Entities - -This code example demonstrates how to use EF Core to query a subset of entities from the database based on specified filters. - -## Code Files: -- [Program.cs](Program.cs) -- [LibraryContext.cs](../shared/LibraryContext.cs) -- [Book.cs](../shared/Book.cs) -- [Author.cs](../shared/Author.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-all-entities/README.md b/content/efcore/getting-started/samples/loading-all-entities/README.md deleted file mode 100644 index 35b8f2b..0000000 --- a/content/efcore/getting-started/samples/loading-all-entities/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Loading All Entities - -This code example demonstrates how to use EF Core to query all entities from the database. - -## Code Files: -- [Program.cs](Program.cs) -- [LibraryContext.cs](../shared/LibraryContext.cs) -- [Book.cs](../shared/Book.cs) -- [Author.cs](../shared/Author.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/count-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/count-method/Program.cs new file mode 100644 index 0000000..3e275ed --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/count-method/Program.cs @@ -0,0 +1,21 @@ +using System; +using System.Linq; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var author = context.Authors + .Single(a => a.LastName == "Cather"); + + var numBooks = context.Entry(author) + .Collection(a => a.Books) + .Query() + .Count(); + + Console.WriteLine("Count: {0}", numBooks); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/count-method/README.md b/content/efcore/getting-started/samples/loading-related-data/count-method/README.md new file mode 100644 index 0000000..87644e9 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/count-method/README.md @@ -0,0 +1,11 @@ +# Count Method + +This code example demonstrates how to use EF Core to query related data from the database using the .Count method. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/field-not-included/Program.cs b/content/efcore/getting-started/samples/loading-related-data/field-not-included/Program.cs new file mode 100644 index 0000000..c297d9f --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/field-not-included/Program.cs @@ -0,0 +1,17 @@ +using System; +using System.Linq; +using Newtonsoft.Json; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var book = context.Books + .Single(b => b.BookId == 1); + + Console.WriteLine(JsonConvert.SerializeObject(book, Formatting.Indented)); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md b/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md new file mode 100644 index 0000000..741e549 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md @@ -0,0 +1,11 @@ +# Field Not Included + +This code example demonstrates how EF Core loads entities from a database and that non-primative types will not be included. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs new file mode 100644 index 0000000..5f41446 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs @@ -0,0 +1,25 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var book = context.Books + .Include(b => b.Editions) + .ThenInclude(e => e.Publisher) + .Include(b => b.Author) + .Single(b => b.Title.Contains("Call of the Wild")); + + Console.WriteLine(String.Format("{0}", book.Title)); + Console.WriteLine("Editions:"); + foreach (Edition edition in book.Editions) + { + Console.WriteLine("{0} - {1}", edition.Year, edition.Publisher.Name); + } + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md new file mode 100644 index 0000000..9ba4eee --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md @@ -0,0 +1,11 @@ +# Then Include Method Chaining + +This code example demonstrates how to use EF Core to load multiple levels and layers of related data from the database by chaining the .Include and .ThenInclude method. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs new file mode 100644 index 0000000..b97aadd --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs @@ -0,0 +1,18 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var book = context.Books + .Include(b => b.Author) + .Single(b => b.BookId == 1); + + Console.WriteLine("{0} - {1} {2}", book.Title, book.Author.FirstName, book.Author.LastName); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/include-method/README.md b/content/efcore/getting-started/samples/loading-related-data/include-method/README.md new file mode 100644 index 0000000..de0c0cf --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/include-method/README.md @@ -0,0 +1,11 @@ +# Include Method + +This code example demonstrates how to use EF Core to load related data from the database using the .Include method. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/load-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/load-method/Program.cs new file mode 100644 index 0000000..22a7147 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/load-method/Program.cs @@ -0,0 +1,23 @@ +using System; +using System.Linq; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var author = context.Authors + .Single(a => a.LastName == "Twain"); + + context.Entry(author) + .Collection(a => a.Books) + .Load(); + + foreach (Book book in author.Books) + { + Console.WriteLine(book.Title); + } + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/load-method/README.md b/content/efcore/getting-started/samples/loading-related-data/load-method/README.md new file mode 100644 index 0000000..8614ac1 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/load-method/README.md @@ -0,0 +1,11 @@ +# Load Method + +This code example demonstrates how to use EF Core to load related data from the database using the .Load method. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/min-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/min-method/Program.cs new file mode 100644 index 0000000..616973e --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/min-method/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var book = context.Books + .Single(b => b.Title == "The Scarlet Plague"); + + var year = context.Entry(book) + .Collection(b => b.Editions) + .Query() + .Min(e => e.Year); + + Console.WriteLine("Minimum Year: " + year); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/min-method/README.md b/content/efcore/getting-started/samples/loading-related-data/min-method/README.md new file mode 100644 index 0000000..e562140 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/min-method/README.md @@ -0,0 +1,11 @@ +# Min Method + +This code example demonstrates how to use EF Core to query related data from the database using the .Min method. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs new file mode 100644 index 0000000..4e5d6d1 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var book = context.Books + .Include(b => b.Editions) + .Include(b => b.Author) + .Single(b => b.BookId == 1); + + foreach (Edition edition in book.Editions) + { + Console.WriteLine("{0}: {1} {2}, {3}", edition.Book.Title, book.Author.FirstName, book.Author.LastName, edition.Year); + } + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md new file mode 100644 index 0000000..7391a99 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md @@ -0,0 +1,11 @@ +# Multiple Include Methods + +This code example demonstrates how to use EF Core to load related data from the database using multiple .Include methods. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/query-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/query-method/Program.cs new file mode 100644 index 0000000..a993e7a --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/query-method/Program.cs @@ -0,0 +1,26 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var author = context.Authors + .Single(a => a.LastName == "Twain"); + + context.Entry(author) + .Collection(a => a.Books) + .Query() + .Where(b => b.Title.Contains("Huck")) + .Load(); + + foreach (var book in author.Books) + { + Console.WriteLine(book.Title); + } + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/query-method/README.md b/content/efcore/getting-started/samples/loading-related-data/query-method/README.md new file mode 100644 index 0000000..16cea72 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/query-method/README.md @@ -0,0 +1,11 @@ +# Query Method + +This code example demonstrates how to use EF Core to load and query related data from the database using the .Query method. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs new file mode 100644 index 0000000..117a295 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs @@ -0,0 +1,26 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var author = context.Authors + .Include(a => a.Books) + .ThenInclude(b => b.Editions) + .ThenInclude(e => e.Publisher) + .Single(a => a.LastName == "Douglass"); + + foreach (Book book in author.Books) + { + foreach (Edition edition in book.Editions) + { + Console.WriteLine("{0}: {1} - {2}", book.Title, edition.Year, edition.Publisher.Name); + } + } + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md new file mode 100644 index 0000000..28a5b8c --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md @@ -0,0 +1,11 @@ +# Then Include Method Chaining + +This code example demonstrates how to use EF Core to load multiple levels and layers of related data from the database by chaining the .ThenInclude method. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs new file mode 100644 index 0000000..27c3e32 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var book = context.Books + .Include(b => b.Editions) + .ThenInclude(e => e.Publisher) + .Single(b => b.BookId == 1); + + foreach (Edition edition in book.Editions) + { + Console.WriteLine("{0} - {1}", edition.Book.Title, edition.Publisher.Name); + } + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md b/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md new file mode 100644 index 0000000..0510c0b --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md @@ -0,0 +1,11 @@ +# Then Include Method + +This code example demonstrates how to use EF Core to load multiple levels of related data from the database using the .ThenInclude method. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-single-entity/README.md b/content/efcore/getting-started/samples/loading-single-entity/README.md deleted file mode 100644 index 59c4aa7..0000000 --- a/content/efcore/getting-started/samples/loading-single-entity/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Loading A Single Entity - -This code example demonstrates how to use EF Core to query a single entity from the database. - -## Code Files: -- [Program.cs](Program.cs) -- [LibraryContext.cs](../shared/LibraryContext.cs) -- [Book.cs](../shared/Book.cs) -- [Author.cs](../shared/Author.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/filtering-entities/Program.cs b/content/efcore/getting-started/samples/querying/filtering-entities/Program.cs similarity index 100% rename from content/efcore/getting-started/samples/filtering-entities/Program.cs rename to content/efcore/getting-started/samples/querying/filtering-entities/Program.cs diff --git a/content/efcore/getting-started/samples/querying/filtering-entities/README.md b/content/efcore/getting-started/samples/querying/filtering-entities/README.md new file mode 100644 index 0000000..420a5f0 --- /dev/null +++ b/content/efcore/getting-started/samples/querying/filtering-entities/README.md @@ -0,0 +1,11 @@ +# Filtering Entities + +This code example demonstrates how to use EF Core to query a subset of entities from the database based on specified filters. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-all-entities/Program.cs b/content/efcore/getting-started/samples/querying/loading-all-entities/Program.cs similarity index 100% rename from content/efcore/getting-started/samples/loading-all-entities/Program.cs rename to content/efcore/getting-started/samples/querying/loading-all-entities/Program.cs diff --git a/content/efcore/getting-started/samples/querying/loading-all-entities/README.md b/content/efcore/getting-started/samples/querying/loading-all-entities/README.md new file mode 100644 index 0000000..cd06c39 --- /dev/null +++ b/content/efcore/getting-started/samples/querying/loading-all-entities/README.md @@ -0,0 +1,11 @@ +# Loading All Entities + +This code example demonstrates how to use EF Core to query all entities from the database. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-single-entity/Program.cs b/content/efcore/getting-started/samples/querying/loading-single-entity/Program.cs similarity index 100% rename from content/efcore/getting-started/samples/loading-single-entity/Program.cs rename to content/efcore/getting-started/samples/querying/loading-single-entity/Program.cs diff --git a/content/efcore/getting-started/samples/querying/loading-single-entity/README.md b/content/efcore/getting-started/samples/querying/loading-single-entity/README.md new file mode 100644 index 0000000..1080caf --- /dev/null +++ b/content/efcore/getting-started/samples/querying/loading-single-entity/README.md @@ -0,0 +1,11 @@ +# Loading A Single Entity + +This code example demonstrates how to use EF Core to query a single entity from the database. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/Author.cs b/content/efcore/getting-started/samples/shared/Author.cs index 8bd1c6a..88cc2d8 100644 --- a/content/efcore/getting-started/samples/shared/Author.cs +++ b/content/efcore/getting-started/samples/shared/Author.cs @@ -1,6 +1,9 @@ +using System.Collections.Generic; + public class Author { public int AuthorId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } + public List Books { get; set; } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/Book.cs b/content/efcore/getting-started/samples/shared/Book.cs index 01e5070..59d2071 100644 --- a/content/efcore/getting-started/samples/shared/Book.cs +++ b/content/efcore/getting-started/samples/shared/Book.cs @@ -1,9 +1,11 @@ +using System.Collections.Generic; + public class Book { public int BookId { get; set; } public string Title { get; set; } public string Genre { get; set; } public int PublicationYear { get; set; } - public Author Author { get; set; } + public List Editions { get; set; } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/Edition.cs b/content/efcore/getting-started/samples/shared/Edition.cs new file mode 100644 index 0000000..7543d24 --- /dev/null +++ b/content/efcore/getting-started/samples/shared/Edition.cs @@ -0,0 +1,7 @@ +public class Edition +{ + public int EditionId { get; set; } + public Book Book { get; set; } + public int Year { get; set; } + public Publisher Publisher { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/LibraryContext.cs b/content/efcore/getting-started/samples/shared/LibraryContext.cs index 4c169bf..7f4fa9a 100644 --- a/content/efcore/getting-started/samples/shared/LibraryContext.cs +++ b/content/efcore/getting-started/samples/shared/LibraryContext.cs @@ -1,11 +1,12 @@ using Microsoft.EntityFrameworkCore; -using System.Collections.Generic; using REPLHelper; public class LibraryContext : DbContext { public DbSet Books { get; set; } public DbSet Authors { get; set; } + public DbSet Editions { get; set; } + public DbSet Publishers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { diff --git a/content/efcore/getting-started/samples/shared/Publisher.cs b/content/efcore/getting-started/samples/shared/Publisher.cs new file mode 100644 index 0000000..0a6082f --- /dev/null +++ b/content/efcore/getting-started/samples/shared/Publisher.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +public class Publisher +{ + public int PublisherId { get; set; } + public string Name { get; set; } + public List Editions { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index 117193c..cf862ec 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -1,3 +1,4 @@ - [Intro to EF Core](intro-to-ef-core.md) - [Installing EF Core](installing-ef-core.md) -- [Querying Data](querying.md) \ No newline at end of file +- [Querying Data](querying.md) +- [Loading Related Data] (loading-related-data.md) \ No newline at end of file diff --git a/content/efcore/getting-started/tutorial-database-reference.md b/content/efcore/getting-started/tutorial-database-reference.md new file mode 100644 index 0000000..6c29fd4 --- /dev/null +++ b/content/efcore/getting-started/tutorial-database-reference.md @@ -0,0 +1,64 @@ +# Database Tables + +## Authors + +| AuthorId | FirstName | LastName | +|----------|------------|-----------| +| 1 | Jack | London | +| 2 | Mark | Twain | +| 3 | Willa | Cather | +| 4 | Frederick | Douglass | +| 7 | Agatha | Christie | +| 8 | Virginia | Woolf | +| 9 | Frances | Harper | +| 10 | Stephen | Crane | + +## Books + +| BookId | AuthorId | Title | Genre | PublicationYear | +|--------|----------|---------------------------------|------------------|-----------------| +| 1 | 9 | Mrs Dalloway | Literary | 1925 | +| 2 | 1 | The Scarlet Plague | Science Fiction | 1912 | +| 3 | 8 | The Secret Adversary | Mystery | 1922 | +| 4 | 5 | My Bondage and My Freedom | Narrative | 1855 | +| 5 | 4 | My Antonia | Historical | 1918 | +| 6 | 4 | O Pioneers! | Historical | 1913 | +| 7 | 2 | Adventures of Huckleberry Finn | Satire | 1884 | +| 8 | 2 | The Adventures of Tom Sawyer | Satire | 1876 | +| 9 | 10 | Iola Leroy | Historical | 1892 | +| 10 | 8 | Murder on the Orient Express | Mystery | 1934 | +| 11 | 1 | The Call of the Wild | Adventure | 1903 | +| 12 | 4 | Death Comes for the Archbishop | Historical | 1927 | + +## Editions + +| EditionId | BookId | PublisherId | Year | +|----------|------------|-----------| --------- | +| 1 | 2 | 2 | 1647 | +| 2 | 2 | 4 | 1656 | +| 3 | 8 | 2 | 2014| +| 4 | 11 | 4 | 2013 | +| 5 | 6 | 5 | 1837 | +| 6 | 1 | 3 | 2000 | +| 7 | 10 | 1 | 1820 | +| 8 | 12 | 5 | 1999 | +| 9 | 3 | 1 | 2012 | +| 10 | 4 | 4 | 1969 | +| 11 | 10 | 1 | 2011 | +| 12 | 7 | 6 | 1974 | +| 13 | 9 | 4 | 2010 | +| 14 | 5 | 2 | 2015 | +| 15 | 2 | 7 | 1929 | + +## Publishers + +| PublisherId | Name | +|----------|------------| +| 1 | HarperCollins Publishers | +| 2 | CreateSpace Independent Publishing Platform | +| 3 | Penguin Books | +| 4 | Dover Publications| +| 5 | University of Nebraska Press| +| 6 | Signet Classics | +| 7 | The Macmillan Company | + \ No newline at end of file diff --git a/content/efcore/getting-started/tutorial-model-reference.md b/content/efcore/getting-started/tutorial-model-reference.md new file mode 100644 index 0000000..a973ced --- /dev/null +++ b/content/efcore/getting-started/tutorial-model-reference.md @@ -0,0 +1,55 @@ +# Entity Classes + +In code, our entity classes look like: + +## Author + +```{.snippet} +public class Author +{ +public int AuthorId { get; set; } +public string FirstName { get; set; } +public string LastName { get; set; } + +public List Books { get; set; } +} +``` + +## Book + +```{.snippet} +public class Book +{ +public int BookId { get; set; } +public string Title { get; set; } +public string Genre { get; set; } +public int PublicationYear { get; set; } + +public Author Author { get; set; } +} +``` + +## Edition + +```{.snippet} +public class Edition +{ +public int EditionId { get; set; } +public int Year { get; set; } + +public Book Book { get; set; } +public Publisher Publisher {get; set;} +} +``` + +## Publisher + +```{.snippet} +public class Publisher +{ +public int PublisherId { get; set; } +public string Name { get; set; } + +public List Editions { get; set; } +} +``` \ No newline at end of file From 82b66ae800268006c1fa17a2f3a96b64dcaa26dc Mon Sep 17 00:00:00 2001 From: arynhuck Date: Mon, 12 Dec 2016 00:26:20 -0600 Subject: [PATCH 25/56] Resolves #7 - Manipulating Entities Tutorial --- content/efcore/getting-started/README.md | 3 +- .../getting-started/manipulating-entities.md | 135 ++++++++++++++++++ .../add-new-entity-to-existing/Program.cs | 32 +++++ .../add-new-entity-to-existing/README.md | 11 ++ .../adding-entities/Program.cs | 24 ++++ .../adding-entities/README.md | 11 ++ .../adding-related-entities/Program.cs | 37 +++++ .../adding-related-entities/README.md | 11 ++ .../deleting-entities/Program.cs | 25 ++++ .../deleting-entities/README.md | 11 ++ .../shared/LibraryContext.cs | 15 ++ .../updating-entities/Program.cs | 25 ++++ .../updating-entities/README.md | 11 ++ .../updating-untracked-entities/Program.cs | 27 ++++ .../updating-untracked-entities/README.md | 11 ++ content/efcore/getting-started/toc.md | 3 +- 16 files changed, 390 insertions(+), 2 deletions(-) create mode 100644 content/efcore/getting-started/manipulating-entities.md create mode 100644 content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs create mode 100644 content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md create mode 100644 content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs create mode 100644 content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md create mode 100644 content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/Program.cs create mode 100644 content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md create mode 100644 content/efcore/getting-started/samples/manipulating-entities/deleting-entities/Program.cs create mode 100644 content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md create mode 100644 content/efcore/getting-started/samples/manipulating-entities/shared/LibraryContext.cs create mode 100644 content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs create mode 100644 content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md create mode 100644 content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs create mode 100644 content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 9c1c457..8ea0975 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -16,4 +16,5 @@ This tutorial will cover the following topics: - [Intro to EF Core](intro-to-ef-core.md) - [Installing EF Core](installing-ef-core.md) - [Querying Data](querying.md) -- [Loading Related Data] (loading-related-data.md) +- [Loading Related Data](loading-related-data.md) +- [Manipulating Entities](manipulating-entities.md) diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md new file mode 100644 index 0000000..aad6a78 --- /dev/null +++ b/content/efcore/getting-started/manipulating-entities.md @@ -0,0 +1,135 @@ +# Manipulating Entities + +Four operations that we often perform on a record in a database are create, read, update, and delete (commonly referred to as "CRUD" operations). We walked through how to read records from a database in the [Querying Data](querying.md) tutorial. Now let's learn how to perform the other CRUD operations which allow us to manipulate records in the database. + +## Adding Entities to a Database + +Let's first look at how to create a new record in the database. In the following example, we create a new author and add it to the database: + +```{.snippet} +using (var context = new LibraryContext()) +{ + var author = new Author + { + FirstName = "Mary", + LastName = "Shelley", + Books = new List() + }; + context.Authors.Add(author); + context.SaveChanges(); +} +``` +:::repl{data-name=adding-entities} +::: + +As you can see, it is easy to add new entities to the database with EF Core. First, we add the entity to the database using the `Add` method of the `DbSet`, much like we would when adding items to a `List`. Next, we call the context's `SaveChanges` method. This step is essential because rather than write changes to the database right away, EF Core keeps track of all the pending changes and waits to write them until `SaveChanges` is called. + +Notice that we do not specify the `AuthorId` property before adding the author to the database. This is because `AuthorId` is a generated property, meaning EF Core will automatically generate a value for it. + +## Adding Related Data + +In the previous example, we added an author without any books to the database. Now we want to add an author and their books to the database. To add related entities like this to the database using EF Core we simply call the `Add` method on the parent entity. It will then automatically add the parent’s related entities to the database. In the following example, we add an author and their books to the database by simply adding the author: + +```{.snippet} +using (var context = new LibraryContext()) +{ + var author = new Author + { + FirstName = "Mary", + LastName = "Shelley", + Books = new List { + new Book + { + Title = "Frankenstein: or, The Modern Prometheus", + Genre = "Science Fiction", + PublicationYear = 1818 + } + } + }; + context.Authors.Add(author); + context.SaveChanges(); +} +``` +:::repl{data-name=adding-related-entities} +::: + +If we want to add a new entity that is related to an existing entity, we first load the existing entity, then add the related entity to it. For example, to add a new book to an existing author we would load the author and then add the book to the author's list of books. Calling `SaveChanges` would then add the new book to the database. + +```{.snippet} +using (var context = new LibraryContext()) +{ + var author = context.Authors + .Include(a => a.Books) + .Single(a => a.LastName == "Crane"); + + var book = new Book + { + Title = "The Red Badge of Courage", + Genre = "War Novel", + PublicationYear = 1871 + }; + + author.Books.Add(book); + context.SaveChanges(); +} +``` +:::repl{data-name=add-new-entity-to-existing} +::: + +## Updating Entities in a Database + +Next, let's look at how to update records that are already in the database. In the following example, we update the title of the first book in the database: + +```{.snippet} +using (var context = new LibraryContext()) +{ + var book = context.Books.First(); + book.Title = "Frankenstein: or, The Modern Prometheus"; + context.SaveChanges(); +} +``` +:::repl{data-name=updating-entities} +::: + +Notice we did not have to tell EF Core that the entity had been changed to update its values. This is because the book we retrieved from the database is a *Tracked Entity*, meaning EF Core will keep track of any changes made to it. EF Core will continue to track changes made to the entity until the context is disposed, which occurs automatically when leaving the `using` block. To learn more about tracked entities, check out the ["Tracking vs. No-Tracking"](https://docs.microsoft.com/en-us/ef/core/querying/tracking) page in the docs. + +Suppose you want to update an untracked entity. As long as the untracked entity has the same primary key as the record in the database, you can accomplish this using the `DbSet`'s `Update` method. In the following example, we update the book with a primary key of `1`: + +```{.snippet} +using (var context = new LibraryContext()) +{ + var book = new Book() + { + BookId = 1, + Title = "Frankenstein: or, The Modern Prometheus", + Genre = "Science Fiction", + PublicationYear = 1818 + }; + context.Books.Update(book); + context.SaveChanges(); +} +``` +:::repl{data-name=updating-untracked-entities} +::: + +## Deleting Entities + +Finally, let's look at how to delete records from the database. This can be accomplished using the `DbSet`'s `Remove` method. The following example demonstrates removing a book from the database: + +```{.snippet} +using (var context = new LibraryContext()) +{ + var book = context.Books.First(); + context.Books.Remove(book); + context.SaveChanges(); +} +``` +:::repl{data-name=deleting-entities} +::: + +## Deleting Related Data + +In the previous example, we were able to successfully delete a book, but what happened to that book's editions and publishers? The short answer is it depends. The way that EF Core handles deletion of an entity with related data depends on several factors including whether the related data is tracked, how EF Core is configured, and how the database is configured. To learn more about the available behaviors and how to configure a certain behavior, check out the [Cascade Delete]() lesson. + +> **Note** {.note} +> The Cascade Delete lesson has not been added yet. For now, please refer to the [Cascade Delete](https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete) page in the docs. \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs new file mode 100644 index 0000000..347359c --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs @@ -0,0 +1,32 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var author = context.Authors + .Include(a => a.Books) + .Single(a => a.LastName == "Crane"); + + var book = new Book + { + Title = "The Red Badge of Courage", + Genre = "War Novel", + PublicationYear = 1871 + }; + + author.Books.Add(book); + context.SaveChanges(); + + var addedBook = context.Books + .Include(b => b.Author) + .Single(b => b.Title.Contains("Badge")); + + Console.WriteLine("{0}: {1}, {2} {3}", addedBook.BookId, addedBook.Title, addedBook.Author.FirstName, addedBook.Author.LastName); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md new file mode 100644 index 0000000..00f3044 --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md @@ -0,0 +1,11 @@ +# Add New Entity To Existing + +This code example demonstrates how to use EF Core to add a new entity to an existing entity. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) +- [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs new file mode 100644 index 0000000..993c5f7 --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.Linq; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var author = new Author + { + FirstName = "Mary", + LastName = "Shelley" + }; + context.Authors.Add(author); + context.SaveChanges(); + + var addedAuthor = context.Authors + .Single(a => a.LastName.Contains("Shelley")); + + Console.WriteLine("{0}: {1} {2}", addedAuthor.AuthorId, addedAuthor.FirstName, addedAuthor.LastName); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md new file mode 100644 index 0000000..971d87c --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md @@ -0,0 +1,11 @@ +# Adding Entities + +This code example demonstrates how to use EF Core to add entities to a database. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) +- [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/Program.cs new file mode 100644 index 0000000..07715b1 --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/Program.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var author = new Author + { + FirstName = "Mary", + LastName = "Shelley", + Books = new List { + new Book + { + Title = "Frankenstein: or, The Modern Prometheus", + Genre = "Science Fiction", + PublicationYear = 1818 + } + } + }; + context.Authors.Add(author); + context.SaveChanges(); + + var addedAuthor = context.Authors + .Include(a => a.Books) + .Single(a => a.LastName.Contains("Shelley")); + + foreach (Book book in addedAuthor.Books) { + Console.WriteLine("{0} - {1}, {2}", book.Title, book.Genre, book.PublicationYear); + } + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md new file mode 100644 index 0000000..6c6951a --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md @@ -0,0 +1,11 @@ +# Adding Related Entities + +This code example demonstrates how to use EF Core to add related entities to a database. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) +- [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/Program.cs new file mode 100644 index 0000000..49e5391 --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/Program.cs @@ -0,0 +1,25 @@ +using System; +using System.Linq; + +public class Program +{ + public static void Main() + { + using (LibraryContext context = new LibraryContext()) { + var authorToDelete = context.Authors + .Single(a => a.LastName == "Crane"); + context.Authors.Remove(authorToDelete); + context.SaveChanges(); + + try + { + var author = context.Authors + .Single(a => a.LastName == "Crane"); + } + catch + { + Console.WriteLine("Author not found!"); + } + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md new file mode 100644 index 0000000..13e324e --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md @@ -0,0 +1,11 @@ +# Deleting Entities + +This code example demonstrates how to use EF Core to delete entities from a database. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) +- [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/shared/LibraryContext.cs b/content/efcore/getting-started/samples/manipulating-entities/shared/LibraryContext.cs new file mode 100644 index 0000000..339da3f --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/shared/LibraryContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using REPLHelper; + +public class LibraryContext : DbContext +{ + public DbSet Books { get; set; } + public DbSet Authors { get; set; } + public DbSet Editions { get; set; } + public DbSet Publishers { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite(DBHelper.GetWriteableDbConnectionString()); + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs new file mode 100644 index 0000000..eddda42 --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs @@ -0,0 +1,25 @@ +using System; +using System.Linq; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var book = context.Books.First(); + + Console.WriteLine(String.Format("Original Book - {0}: {1}", book.BookId, book.Title)); + + book.Title = "Frankenstein: or, The Modern Prometheus"; + context.SaveChanges(); + } + + using (var context = new LibraryContext()) { + var updatedBook = context.Books + .Single(b => b.Title.Contains("Frankenstein")); + + Console.WriteLine(String.Format("Updated Book - {0}: {1}", updatedBook.BookId, updatedBook.Title)); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md new file mode 100644 index 0000000..f1564c3 --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md @@ -0,0 +1,11 @@ +# Updating Entities + +This code example demonstrates how to use EF Core to update entities to a database. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) +- [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs new file mode 100644 index 0000000..64569fa --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs @@ -0,0 +1,27 @@ +using System; +using System.Linq; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var untrackedBook = new Book() + { + BookId = 1, + Title = "Frankenstein: or, The Modern Prometheus", + Genre = "Science Fiction", + PublicationYear = 1818 + }; + + context.Books.Update(untrackedBook); + context.SaveChanges(); + + var updatedBook = context.Books + .Single(b => b.BookId == 1); + + Console.WriteLine("{0}: {1}, {2} {3}", updatedBook.BookId, updatedBook.Title, updatedBook.Genre, updatedBook.PublicationYear); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md new file mode 100644 index 0000000..32880a5 --- /dev/null +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md @@ -0,0 +1,11 @@ +# Updating Untracked Entities + +This code example demonstrates how to use EF Core to update untracked entities in a database. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) +- [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [Edition.cs](../../shared/Edition.cs) +- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index cf862ec..9249c92 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -1,4 +1,5 @@ - [Intro to EF Core](intro-to-ef-core.md) - [Installing EF Core](installing-ef-core.md) - [Querying Data](querying.md) -- [Loading Related Data] (loading-related-data.md) \ No newline at end of file +- [Loading Related Data](loading-related-data.md) +- [Manipulating Entities](manipulating-entities.md) From a0d0ea2171e02e866c613bbffc635572f8ff4b03 Mon Sep 17 00:00:00 2001 From: Ryan Helmoski Date: Sun, 18 Dec 2016 19:39:27 -0600 Subject: [PATCH 26/56] Resolves #55 - C# tutorial code doesn't work with replservice --- .../getting-started/arrays-collections.md | 40 +++++++++---------- content/csharp/getting-started/datetimes.md | 12 +++--- .../getting-started/making-decisions.md | 20 +++++----- content/csharp/getting-started/strings.md | 38 +++++++++--------- .../types-variables-user-input.md | 12 +++--- .../csharp/getting-started/types-variables.md | 8 ++-- 6 files changed, 65 insertions(+), 65 deletions(-) diff --git a/content/csharp/getting-started/arrays-collections.md b/content/csharp/getting-started/arrays-collections.md index fa890af..461a741 100644 --- a/content/csharp/getting-started/arrays-collections.md +++ b/content/csharp/getting-started/arrays-collections.md @@ -26,9 +26,9 @@ int[] otherIntegers = new [] { 1, 3, 5, 7, 9 }; // you can omit `int` and just s ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { int[] someIntegers = new int[3]; // holds 3 elements, with indexes of 0, 1, and 2. // uninitialized elements of a declared array hold the default value for the type (in this case 0). @@ -72,9 +72,9 @@ int[,] someTable = { { 1, 2, 3 }, { 4, 5, 6 } }; // you can fill a multi-dimensi ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { int[,] eggCarton = new int[2,6]; // a typical egg carton can be thought of as a 2x6 array Console.WriteLine(eggCarton[0,0]); // one "corner" of the array @@ -96,9 +96,9 @@ jaggedArray[0] = new int[2] { 1, 2 }; // set values of first array ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { int[][] jaggedArray = new int[4][]; // define first dimension jaggedArray[0] = new int[2] { 1, 2 }; // set values of first array @@ -131,9 +131,9 @@ someIntegers[3] = 3; // EXCEPTION ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { int[] someIntegers = { 1, 2, 3 }; @@ -167,9 +167,9 @@ string[] colors = input.Split(','); // note single quotes, which are used to def ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { string input = "red,blue,yellow,green"; string[] colors = input.Split(','); // note single quotes, which are used to define literal character (``char``) values @@ -189,9 +189,9 @@ Console.WriteLine(output); ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { string input = "red,blue,yellow,green"; string[] colors = input.Split(','); // note single quotes, which are used to define literal character (``char``) values @@ -237,9 +237,9 @@ List colorList = new List(colors); // initialize the list from a using System; using System.Collections.Generic; -class Program +public class Program { - static void Main() + public static void Main() { List someInts = new List(); // declares an empty list someInts.Add(2); // the list now has one item in it: {2} @@ -273,9 +273,9 @@ colors.Clear(); // colors is now an empty list using System; using System.Collections.Generic; -class Program +public class Program { - static void Main() + public static void Main() { List colors = new List() { "black", "white", "gray" }; colors.Remove("black"); @@ -308,9 +308,9 @@ colors.ForEach(Console.WriteLine); // equivalent to ForEach(c => Console.WriteLi using System; using System.Collections.Generic; -class Program +public class Program { - static void Main() + public static void Main() { var colors = new List() { "blue", "green", "yellow" }; colors.ForEach(Console.WriteLine); // equivalent to ForEach(c => Console.WriteLine(c)) @@ -334,9 +334,9 @@ Console.WriteLine(String.Join(",", colors)); using System; using System.Collections.Generic; -class Program +public class Program { - static void Main() + public static void Main() { var colors = new List() { "blue", "green", "yellow" }; Console.WriteLine(String.Join(",", colors)); diff --git a/content/csharp/getting-started/datetimes.md b/content/csharp/getting-started/datetimes.md index 901c879..cb4d163 100644 --- a/content/csharp/getting-started/datetimes.md +++ b/content/csharp/getting-started/datetimes.md @@ -19,9 +19,9 @@ var someDay = DateTime.Parse("7/1/2016"); ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { var currentTime = DateTime.Now; // current time var today = DateTime.Today; // current date - time is midnight @@ -72,9 +72,9 @@ int second = someTime.Second; // 9 ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { var someTime = new DateTime(2016,7,1,11,10,9); // 1 July 2016 11:10:09 AM int year = someTime.Year; // 2016 @@ -107,9 +107,9 @@ Console.WriteLine($"There are {duration.TotalDays} days left in the year"); ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { DateTime nextYear = new DateTime(DateTime.Today.Year+1, 1, 1); TimeSpan duration = nextYear - DateTime.Today; diff --git a/content/csharp/getting-started/making-decisions.md b/content/csharp/getting-started/making-decisions.md index be2de6c..6a578fb 100644 --- a/content/csharp/getting-started/making-decisions.md +++ b/content/csharp/getting-started/making-decisions.md @@ -18,9 +18,9 @@ static void Greet(string name) ```{class=REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { Greet(""); // try calling this with "", null, and your name as arguments } @@ -47,9 +47,9 @@ Console.WriteLine(sum); ```{class=REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { bool someCondition = false; // try it with both true and false values @@ -78,9 +78,9 @@ Console.WriteLine(sum); ```{class=REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { bool someCondition = false; @@ -125,9 +125,9 @@ else ```{class=REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { Console.WriteLine("What is the capital of Ohio?"); var answer = "your answer here"; // change this to your answer @@ -213,9 +213,9 @@ switch (guessedNumber) ```{class=REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { uint guessedNumber = 1; // try different numbers to see resulting behavior switch (guessedNumber) diff --git a/content/csharp/getting-started/strings.md b/content/csharp/getting-started/strings.md index 4a69e1b..e69e4aa 100644 --- a/content/csharp/getting-started/strings.md +++ b/content/csharp/getting-started/strings.md @@ -18,16 +18,16 @@ string string2 = "Hello"; ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { - string string1; // current value is null - string1 = "Hello"; + string string1; // current value is null + string1 = "Hello"; - string string2 = "Hello"; - Console.WriteLine(string1); - Console.WriteLine(string2); + string string2 = "Hello"; + Console.WriteLine(string1); + Console.WriteLine(string2); } } ``` @@ -44,9 +44,9 @@ string empty2 = String.Empty; ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { string empty1 = ""; string empty2 = String.Empty; @@ -84,9 +84,9 @@ Console.WriteLine($"1st string is {emptyString.Length} characters long."); ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { string emptyString = String.Empty; string nullString = null; @@ -119,9 +119,9 @@ string combined = one + two; // "abc123" ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { string one = "abc"; string two = "123"; @@ -145,9 +145,9 @@ string lower2 = "Another Test".ToLower(); // another test ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { string original = "Test string"; string capital = original.ToUpper(); // TEST STRING @@ -174,9 +174,9 @@ string shortversion = input.Trim().Substring(0,3); // "Ste" ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { string input = " Steve "; // has a space at the start and end. string clean1 = input.TrimStart(); // "Steve " @@ -213,9 +213,9 @@ string greet4 = greetTemplate.Replace("**NAME**", name); // Hello Steve! ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { string name = "Steve"; string greet1 = $"Hello {name}!"; // Hello Steve! diff --git a/content/csharp/getting-started/types-variables-user-input.md b/content/csharp/getting-started/types-variables-user-input.md index 21c359c..12a6c65 100644 --- a/content/csharp/getting-started/types-variables-user-input.md +++ b/content/csharp/getting-started/types-variables-user-input.md @@ -18,9 +18,9 @@ Console.WriteLine("Hello World!"); ```{class=REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { Console.WriteLine("Hello World!"); } @@ -38,9 +38,9 @@ var name = "Steve"; // use your name here ```{class=REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { var name = "Steve"; // use your name here Console.WriteLine("Hello World!"); @@ -61,9 +61,9 @@ Console.WriteLine($"Hello {name}!"); ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { var name = "Steve"; // use your name here Console.WriteLine($"Hello {name}!"); diff --git a/content/csharp/getting-started/types-variables.md b/content/csharp/getting-started/types-variables.md index deb44c4..10d06c3 100644 --- a/content/csharp/getting-started/types-variables.md +++ b/content/csharp/getting-started/types-variables.md @@ -13,9 +13,9 @@ Console.WriteLine("Hello World!"); ```{class=REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { Console.WriteLine("Hello World!"); } @@ -47,9 +47,9 @@ Console.WriteLine($"Hello {name}!"); ```{.REPL} using System; -class Program +public class Program { - static void Main() + public static void Main() { var name = "Steve"; // use your name here Console.WriteLine($"Hello {name}!"); From 3eea6efbcf5b9c115dbceda3a37d2ab25c9fb42d Mon Sep 17 00:00:00 2001 From: arynhuck Date: Sat, 21 Jan 2017 20:07:30 -0600 Subject: [PATCH 27/56] Resolves #47 - Update querying tutorial to point to database and model pages --- content/efcore/getting-started/querying.md | 42 ++-------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/content/efcore/getting-started/querying.md b/content/efcore/getting-started/querying.md index df06839..e64aec1 100644 --- a/content/efcore/getting-started/querying.md +++ b/content/efcore/getting-started/querying.md @@ -2,46 +2,8 @@ In this lesson, you'll learn how to use querying to fetch one or more items from your database. EF Core uses LINQ to query data, so it is important that you understand LINQ before going through this lesson. Check out the [LINQ lesson](../../csharp/getting-started/linq.md) in the C# Interactive Tutorial if you need a refresher. -## Example database - -For this lesson, we will use a small database to allow you to try querying on your own. The database has two tables, Books and Authors, and the data is as follows: - -### Books -| BookId | AuthorId | Title | Genre | PublicationYear | -|--------|----------|---------------------------------|------------------|-----------------| -| 1 | 9 | Mrs. Dalloway | Literary | 1925 | -| 2 | 6 | The Mysterious Island | Science Fiction | 1874 | -| 3 | 7 | The Blazing World | Science Fiction | 1666 | -| 4 | 1 | The Scarlet Plague | Science Fiction | 1912 | -| 5 | 8 | The Secret Adversary | Mystery | 1922 | -| 6 | 6 | An Antarctic Mystery | Mystery | 1897 | -| 7 | 5 | My Bondage and My Freedom | Narrative | 1855 | -| 8 | 3 | The Count of Monte Cristo | Adventure | 1845 | -| 9 | 10 | Minnie's Sacrifice | Historical | 1869 | -| 10 | 4 | My Antonia | Historical | 1918 | -| 11 | 4 | O Pioneers! | Historical | 1913 | -| 12 | 2 | Adventures of Huckleberry Finn | Satire | 1884 | -| 13 | 2 | The Adventures of Tom Sawyer | Satire | 1876 | -| 14 | 10 | Iola Leroy | Historical | 1892 | -| 15 | 8 | Murder on the Orient Express | Mystery | 1934 | -| 16 | 1 | The Call of the Wild | Adventure | 1903 | -| 17 | 4 | Death Comes for the Archbishop | Historical | 1927 | - - -### Authors -| AuthorId | FirstName | LastName | -|----------|------------|-----------| -| 1 | Jack | London | -| 2 | Mark | Twain | -| 3 | Alexandre | Dumas | -| 4 | Willa | Cather | -| 5 | Frederick | Douglass | -| 6 | Jules | Vern | -| 7 | Margaret | Cavendish | -| 8 | Agatha | Christie | -| 9 | Virginia | Woolf | -| 10 | Frances | Harper | -| 11 | Stephen | Crane | +> **Note** {.note} +> If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](tutorial-database-reference.md) and [Model Reference](tutorial-model-reference.md) pages. ## Loading All Entities From 692662a26977ec572924b7d06154b1a79af72327 Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Wed, 25 Jan 2017 16:49:18 -0600 Subject: [PATCH 28/56] Resolves #60 - Fixes broken links and adds links to manipulating-entities tutorial --- content/efcore/getting-started/loading-related-data.md | 2 +- content/efcore/getting-started/manipulating-entities.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/content/efcore/getting-started/loading-related-data.md b/content/efcore/getting-started/loading-related-data.md index d576628..11ae1d3 100644 --- a/content/efcore/getting-started/loading-related-data.md +++ b/content/efcore/getting-started/loading-related-data.md @@ -1,7 +1,7 @@ # Loading Related Data > **Note** {.note} -> If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](database-reference.md) and [Model Reference](model-reference) pages. +> If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](tutorial-database-reference.md) and [Model Reference](tutorial-model-reference.md) pages. ## Single Layer Inclusion diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md index aad6a78..ac519db 100644 --- a/content/efcore/getting-started/manipulating-entities.md +++ b/content/efcore/getting-started/manipulating-entities.md @@ -2,6 +2,9 @@ Four operations that we often perform on a record in a database are create, read, update, and delete (commonly referred to as "CRUD" operations). We walked through how to read records from a database in the [Querying Data](querying.md) tutorial. Now let's learn how to perform the other CRUD operations which allow us to manipulate records in the database. +> **Note** {.note} +> If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](tutorial-database-reference.md) and [Model Reference](tutorial-model-reference.md) pages. + ## Adding Entities to a Database Let's first look at how to create a new record in the database. In the following example, we create a new author and add it to the database: From f667efc60b82710c6a3f5c5b41ee32e08f2be883 Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Wed, 25 Jan 2017 18:58:28 -0600 Subject: [PATCH 29/56] Resolves #58 - Updated tutorials to reflect new database schema. * updated cs files to add new ones, edited database reference page, updated all READMEs. Still need to update tutorials and Program.cs files as necessary * updated all code snippets and tutorials to reflect AuthorId/BookId -> Id and new database structure * changed all of the cr's to c's and edited the wording in a couple areas * edit tables so they'll render * minor formatting thing * made min the max method instead, fixed a reference to editions/publishers/fixed wording in model reference, updated db context for writeable * Remove "readers" when talking about deleting book * Make it string not String --- .../getting-started/loading-related-data.md | 48 ++++---- .../getting-started/manipulating-entities.md | 8 +- .../count-method/README.md | 5 +- .../field-not-included/Program.cs | 2 +- .../field-not-included/README.md | 5 +- .../Program.cs | 12 +- .../README.md | 5 +- .../include-method/Program.cs | 2 +- .../include-method/README.md | 5 +- .../load-method/README.md | 5 +- .../max-method/Program.cs | 22 ++++ .../{min-method => max-method}/README.md | 7 +- .../min-method/Program.cs | 22 ---- .../multiple-include-methods/Program.cs | 8 +- .../multiple-include-methods/README.md | 5 +- .../query-method/README.md | 5 +- .../then-include-method-chain/Program.cs | 12 +- .../then-include-method-chain/README.md | 5 +- .../then-include-method/Program.cs | 10 +- .../then-include-method/README.md | 5 +- .../add-new-entity-to-existing/Program.cs | 2 +- .../add-new-entity-to-existing/README.md | 5 +- .../adding-entities/Program.cs | 2 +- .../adding-entities/README.md | 5 +- .../adding-related-entities/README.md | 5 +- .../deleting-entities/README.md | 5 +- .../shared/LibraryContext.cs | 7 +- .../updating-entities/Program.cs | 4 +- .../updating-entities/README.md | 5 +- .../updating-untracked-entities/Program.cs | 6 +- .../updating-untracked-entities/README.md | 5 +- .../querying/filtering-entities/README.md | 5 +- .../querying/loading-all-entities/README.md | 5 +- .../querying/loading-single-entity/Program.cs | 2 +- .../querying/loading-single-entity/README.md | 5 +- .../getting-started/samples/shared/Address.cs | 6 + .../getting-started/samples/shared/Author.cs | 3 +- .../getting-started/samples/shared/Book.cs | 5 +- .../samples/shared/CheckoutRecord.cs | 12 ++ .../getting-started/samples/shared/Edition.cs | 7 -- .../samples/shared/LibraryContext.cs | 7 +- .../samples/shared/Publisher.cs | 8 -- .../getting-started/samples/shared/Reader.cs | 8 ++ .../tutorial-database-reference.md | 108 +++++++++--------- .../tutorial-model-reference.md | 79 ++++++++----- 45 files changed, 281 insertions(+), 228 deletions(-) create mode 100644 content/efcore/getting-started/samples/loading-related-data/max-method/Program.cs rename content/efcore/getting-started/samples/loading-related-data/{min-method => max-method}/README.md (57%) delete mode 100644 content/efcore/getting-started/samples/loading-related-data/min-method/Program.cs create mode 100644 content/efcore/getting-started/samples/shared/Address.cs create mode 100644 content/efcore/getting-started/samples/shared/CheckoutRecord.cs delete mode 100644 content/efcore/getting-started/samples/shared/Edition.cs delete mode 100644 content/efcore/getting-started/samples/shared/Publisher.cs create mode 100644 content/efcore/getting-started/samples/shared/Reader.cs diff --git a/content/efcore/getting-started/loading-related-data.md b/content/efcore/getting-started/loading-related-data.md index 11ae1d3..801497d 100644 --- a/content/efcore/getting-started/loading-related-data.md +++ b/content/efcore/getting-started/loading-related-data.md @@ -11,7 +11,7 @@ When loading an entity from the database, EF Core will automatically include pro using (var context = new LibraryContext()) { var book = context.Books - .Single(b => b.BookId == 1); + .Single(b => b.Id == 1); } ``` :::repl{data-name=field-not-included} @@ -24,21 +24,21 @@ using (var context = new LibraryContext()) { var book = context.Books .Include(b => b.Author) - .Single(b => b.BookId == 1); + .Single(b => b.Id == 1); } ``` :::repl{data-name=include-method} ::: -You can also include multiple non-primitive type properties at once by calling the `Include` method multiple times. For example, we can include the `Editions` and `Authors` properties of the `Book` entity like so: +You can also include multiple non-primitive type properties at once by calling the `Include` method multiple times. For example, we can include the `CheckoutRecords` and `Author` properties of the `Book` entity like so: ```{.snippet} using (var context = new LibraryContext()) { var book = context.Books - .Include(b => b.Editions) + .Include(b => b.CheckoutRecords) .Include(b => b.Author) - .Single(b => b.BookId == 1); + .Single(b => b.Id == 1); } ``` :::repl{data-name=multiple-include-methods} @@ -46,45 +46,45 @@ using (var context = new LibraryContext()) ## Multi-layer Inclusion -Now, what happens if one of the properties we include also has non-primitive type properties? By default, they won't be loaded from the database, but we can tell EF Core to load them using the `ThenInclude` method. For example, we can load the publisher information for the editions of a book like so: +Now, what happens if one of the properties we include also has non-primitive type properties? By default, they won't be loaded from the database, but we can tell EF Core to load them using the `ThenInclude` method. For example, we can determine all of the readers who have checked out a specific book by using `Include` to load the book's checkout records and then using `ThenInclude` to load the reader associated with each checkout record as shown below: ```{.snippet} using (var context = new LibraryContext()) { var book = context.Book - .Include(b => b.Editions) - .ThenInclude(e => e.Publisher) - .Single(b => b.BookId == 1) ; + .Include(b => b.CheckoutRecords) + .ThenInclude(c => c.Reader) + .Single(b => b.Id == 1); } ``` :::repl{data-name=then-include-method} ::: -We can also chain `ThenInclude` calls to include deeper layers of related data. For example, if we want to find out the publisher information for the different editions of Fredrick Douglass' books in this library, we will need to chain `ThenInclude` calls to get the book, edition, and publisher information. +We can also chain `ThenInclude` calls to include deeper layers of related data. For example, if we want to find out all of the readers who have checked out books written by Frederick Douglass, we will need to chain `ThenInclude` calls to get the associated books, checkout records, and reader information. ```{.snippet} using (var context = new LibraryContext()) { var author = context.Authors .Include(a => a.Books) - .ThenInclude(b => b.Editions) - .ThenInclude(e => e.Publisher) + .ThenInclude(b => b.CheckoutRecords) + .ThenInclude(c => c.Reader) .Single(a => a.LastName == "Douglass"); } ``` :::repl{data-name=then-include-method-chain} ::: -A mix of `Include` and `ThenInclude` commands can also be chained together to include related data from multiple layers across related entities. In the following example, we are looking for the author, editions, and edition publishers of _The Call of the Wild_. +A mix of `Include` and `ThenInclude` commands can also be chained together to include related data from multiple layers across related entities. In the following example, we chain together `Include` and `ThenInclude` commands to load the author of _Murder on the Orient Express_, as well as all of the readers who have checked it out. ```{.snippet} using (var context = new LibraryContext()) { - var book = context.Books - .Include(b => b.Editions) - .ThenInclude(e => e.Publisher) - .Include(b => b.Author) - .Single(b => b.Title.Contains("Call of the Wild")); + var book = context.Books + .Include(c => c.CheckoutRecords) + .ThenInclude(r => r.Reader) + .Include(b => b.Author) + .Single(b => b.Title.Contains("Orient Express")); } ``` :::repl{data-name=include-and-then-include-method-chain} @@ -154,20 +154,20 @@ using (var context = new LibraryContext()) :::repl{data-name=count-method} ::: -Likewise, we can find the year of the oldest edition of a book using the `Min` method: +Likewise, we can find the most recent date a specific book was checked out using the `Max` method: ```{.snippet} using (var context = new LibraryContext()) { var book = context.Books - .Single(b => b.Title == "The Scarlet Plague"); + .Single(b => b.Title.Contains("Orient Express")); - var year = context.Entry(book) - .Collection(b => b.Editions) + var mostRecentCheckout = context.Entry(book) + .Collection(b => b.CheckoutRecords) .Query() - .Min(e => e.Year); + .Max(c => c.CheckoutDate); } ``` -:::repl{data-name=min-method} +:::repl{data-name=max-method} ::: \ No newline at end of file diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md index ac519db..f5da559 100644 --- a/content/efcore/getting-started/manipulating-entities.md +++ b/content/efcore/getting-started/manipulating-entities.md @@ -27,7 +27,7 @@ using (var context = new LibraryContext()) As you can see, it is easy to add new entities to the database with EF Core. First, we add the entity to the database using the `Add` method of the `DbSet`, much like we would when adding items to a `List`. Next, we call the context's `SaveChanges` method. This step is essential because rather than write changes to the database right away, EF Core keeps track of all the pending changes and waits to write them until `SaveChanges` is called. -Notice that we do not specify the `AuthorId` property before adding the author to the database. This is because `AuthorId` is a generated property, meaning EF Core will automatically generate a value for it. +Notice that we do not specify the `Id` property before adding the author to the database. This is because `Id` is a generated property, meaning EF Core will automatically generate a value for it. ## Adding Related Data @@ -103,7 +103,7 @@ using (var context = new LibraryContext()) { var book = new Book() { - BookId = 1, + Id = 1, Title = "Frankenstein: or, The Modern Prometheus", Genre = "Science Fiction", PublicationYear = 1818 @@ -132,7 +132,7 @@ using (var context = new LibraryContext()) ## Deleting Related Data -In the previous example, we were able to successfully delete a book, but what happened to that book's editions and publishers? The short answer is it depends. The way that EF Core handles deletion of an entity with related data depends on several factors including whether the related data is tracked, how EF Core is configured, and how the database is configured. To learn more about the available behaviors and how to configure a certain behavior, check out the [Cascade Delete]() lesson. +In the previous example, we were able to successfully delete a book, but what happened to that book's checkout records? The short answer is it depends. The way that EF Core handles deletion of an entity with related data depends on several factors including whether the related data is tracked, how EF Core is configured, and how the database is configured. To learn more about the available behaviors and how to configure a certain behavior, check out the [Cascade Delete]() lesson. > **Note** {.note} -> The Cascade Delete lesson has not been added yet. For now, please refer to the [Cascade Delete](https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete) page in the docs. \ No newline at end of file +> The Cascade Delete lesson has not been added yet. For now, please refer to the [Cascade Delete](https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete) page in the docs. diff --git a/content/efcore/getting-started/samples/loading-related-data/count-method/README.md b/content/efcore/getting-started/samples/loading-related-data/count-method/README.md index 87644e9..6023b40 100644 --- a/content/efcore/getting-started/samples/loading-related-data/count-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/count-method/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to query related data from the - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/field-not-included/Program.cs b/content/efcore/getting-started/samples/loading-related-data/field-not-included/Program.cs index c297d9f..9b6c4ef 100644 --- a/content/efcore/getting-started/samples/loading-related-data/field-not-included/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/field-not-included/Program.cs @@ -9,7 +9,7 @@ public static void Main() using (var context = new LibraryContext()) { var book = context.Books - .Single(b => b.BookId == 1); + .Single(b => b.Id == 1); Console.WriteLine(JsonConvert.SerializeObject(book, Formatting.Indented)); } diff --git a/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md b/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md index 741e549..978220e 100644 --- a/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md @@ -7,5 +7,6 @@ This code example demonstrates how EF Core loads entities from a database and th - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs index 5f41446..3adda8d 100644 --- a/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs @@ -9,16 +9,16 @@ public static void Main() using (var context = new LibraryContext()) { var book = context.Books - .Include(b => b.Editions) - .ThenInclude(e => e.Publisher) + .Include(b => b.CheckoutRecords) + .ThenInclude(c => c.Reader) .Include(b => b.Author) - .Single(b => b.Title.Contains("Call of the Wild")); + .Single(b => b.Title.Contains("Orient Express")); Console.WriteLine(String.Format("{0}", book.Title)); - Console.WriteLine("Editions:"); - foreach (Edition edition in book.Editions) + Console.WriteLine("Checkout Records:"); + foreach (CheckoutRecord checkoutRecord in book.CheckoutRecords) { - Console.WriteLine("{0} - {1}", edition.Year, edition.Publisher.Name); + Console.WriteLine("{0} {1} - Due {2}", checkoutRecord.Reader.FirstName, checkoutRecord.Reader.LastName, checkoutRecord.DueDate.ToString("MMMM dd, yyyy")); } } } diff --git a/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md index 9ba4eee..9beffc6 100644 --- a/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to load multiple levels and la - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs index b97aadd..1de4fec 100644 --- a/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs @@ -10,7 +10,7 @@ public static void Main() { var book = context.Books .Include(b => b.Author) - .Single(b => b.BookId == 1); + .Single(b => b.Id == 1); Console.WriteLine("{0} - {1} {2}", book.Title, book.Author.FirstName, book.Author.LastName); } diff --git a/content/efcore/getting-started/samples/loading-related-data/include-method/README.md b/content/efcore/getting-started/samples/loading-related-data/include-method/README.md index de0c0cf..3c9a0a2 100644 --- a/content/efcore/getting-started/samples/loading-related-data/include-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/include-method/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to load related data from the - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/load-method/README.md b/content/efcore/getting-started/samples/loading-related-data/load-method/README.md index 8614ac1..e4fbe4c 100644 --- a/content/efcore/getting-started/samples/loading-related-data/load-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/load-method/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to load related data from the - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/max-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/max-method/Program.cs new file mode 100644 index 0000000..83f9a16 --- /dev/null +++ b/content/efcore/getting-started/samples/loading-related-data/max-method/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Linq; +using Microsoft.EntityFrameworkCore; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + var book = context.Books + .Single(b => b.Title.Contains("Orient Express")); + + var mostRecentCheckout = context.Entry(book) + .Collection(b => b.CheckoutRecords) + .Query() + .Max(c => c.CheckoutDate); + + Console.WriteLine("Earliest Checkout: {0}", mostRecentCheckout.ToString("MMMM dd, yyyy")); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/min-method/README.md b/content/efcore/getting-started/samples/loading-related-data/max-method/README.md similarity index 57% rename from content/efcore/getting-started/samples/loading-related-data/min-method/README.md rename to content/efcore/getting-started/samples/loading-related-data/max-method/README.md index e562140..6aa2a3e 100644 --- a/content/efcore/getting-started/samples/loading-related-data/min-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/max-method/README.md @@ -1,11 +1,12 @@ # Min Method -This code example demonstrates how to use EF Core to query related data from the database using the .Min method. +This code example demonstrates how to use EF Core to query related data from the database using the .Max method. ## Code Files: - [Program.cs](Program.cs) - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/min-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/min-method/Program.cs deleted file mode 100644 index 616973e..0000000 --- a/content/efcore/getting-started/samples/loading-related-data/min-method/Program.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Linq; -using Microsoft.EntityFrameworkCore; - -public class Program -{ - public static void Main() - { - using (var context = new LibraryContext()) - { - var book = context.Books - .Single(b => b.Title == "The Scarlet Plague"); - - var year = context.Entry(book) - .Collection(b => b.Editions) - .Query() - .Min(e => e.Year); - - Console.WriteLine("Minimum Year: " + year); - } - } -} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs index 4e5d6d1..8781e6b 100644 --- a/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs @@ -9,13 +9,13 @@ public static void Main() using (var context = new LibraryContext()) { var book = context.Books - .Include(b => b.Editions) + .Include(b => b.CheckoutRecords) .Include(b => b.Author) - .Single(b => b.BookId == 1); + .Single(b => b.Id == 1); - foreach (Edition edition in book.Editions) + foreach (CheckoutRecord checkoutRecord in book.CheckoutRecords) { - Console.WriteLine("{0}: {1} {2}, {3}", edition.Book.Title, book.Author.FirstName, book.Author.LastName, edition.Year); + Console.WriteLine("{0}: {1} {2}, Due {3}", checkoutRecord.Book.Title, book.Author.FirstName, book.Author.LastName, checkoutRecord.DueDate.ToString("MMMM dd, yyyy")); } } } diff --git a/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md index 7391a99..159da96 100644 --- a/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to load related data from the - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/query-method/README.md b/content/efcore/getting-started/samples/loading-related-data/query-method/README.md index 16cea72..475a744 100644 --- a/content/efcore/getting-started/samples/loading-related-data/query-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/query-method/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to load and query related data - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs index 117a295..8d2692a 100644 --- a/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs @@ -8,17 +8,17 @@ public static void Main() { using (var context = new LibraryContext()) { - var author = context.Authors - .Include(a => a.Books) - .ThenInclude(b => b.Editions) - .ThenInclude(e => e.Publisher) + var author = context.Authors + .Include(a => a.Books) + .ThenInclude(b => b.CheckoutRecords) + .ThenInclude(c => c.Reader) .Single(a => a.LastName == "Douglass"); foreach (Book book in author.Books) { - foreach (Edition edition in book.Editions) + foreach (CheckoutRecord checkoutRecord in book.CheckoutRecords) { - Console.WriteLine("{0}: {1} - {2}", book.Title, edition.Year, edition.Publisher.Name); + Console.WriteLine("{0}: Due {1} - {2} {3}", book.Title, checkoutRecord.DueDate.ToString("MMMM dd, yyyy"), checkoutRecord.Reader.FirstName, checkoutRecord.Reader.LastName); } } } diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md index 28a5b8c..6e47b07 100644 --- a/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to load multiple levels and la - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs index 27c3e32..bd41cf6 100644 --- a/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs @@ -9,13 +9,13 @@ public static void Main() using (var context = new LibraryContext()) { var book = context.Books - .Include(b => b.Editions) - .ThenInclude(e => e.Publisher) - .Single(b => b.BookId == 1); + .Include(b => b.CheckoutRecords) + .ThenInclude(c => c.Reader) + .Single(b => b.Id == 1); - foreach (Edition edition in book.Editions) + foreach (CheckoutRecord checkoutRecord in book.CheckoutRecords) { - Console.WriteLine("{0} - {1}", edition.Book.Title, edition.Publisher.Name); + Console.WriteLine("{0} - {1} {2}", checkoutRecord.Book.Title, checkoutRecord.Reader.FirstName, checkoutRecord.Reader.LastName); } } } diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md b/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md index 0510c0b..f57a0d0 100644 --- a/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to load multiple levels of rel - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs index 347359c..6968507 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs +++ b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs @@ -26,7 +26,7 @@ public static void Main() .Include(b => b.Author) .Single(b => b.Title.Contains("Badge")); - Console.WriteLine("{0}: {1}, {2} {3}", addedBook.BookId, addedBook.Title, addedBook.Author.FirstName, addedBook.Author.LastName); + Console.WriteLine("{0}: {1}, {2} {3}", addedBook.Id, addedBook.Title, addedBook.Author.FirstName, addedBook.Author.LastName); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md index 00f3044..4f90668 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to add a new entity to an exis - [LibraryContext.cs](../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs index 993c5f7..d3cc452 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs @@ -18,7 +18,7 @@ public static void Main() var addedAuthor = context.Authors .Single(a => a.LastName.Contains("Shelley")); - Console.WriteLine("{0}: {1} {2}", addedAuthor.AuthorId, addedAuthor.FirstName, addedAuthor.LastName); + Console.WriteLine("{0}: {1} {2}", addedAuthor.Id, addedAuthor.FirstName, addedAuthor.LastName); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md index 971d87c..4a55735 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to add entities to a database. - [LibraryContext.cs](../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md index 6c6951a..069906d 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to add related entities to a d - [LibraryContext.cs](../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md index 13e324e..15d49a7 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to delete entities from a data - [LibraryContext.cs](../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/shared/LibraryContext.cs b/content/efcore/getting-started/samples/manipulating-entities/shared/LibraryContext.cs index 339da3f..b308f4e 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/shared/LibraryContext.cs +++ b/content/efcore/getting-started/samples/manipulating-entities/shared/LibraryContext.cs @@ -3,10 +3,11 @@ public class LibraryContext : DbContext { - public DbSet Books { get; set; } + public DbSet
Addresses { get; set; } public DbSet Authors { get; set; } - public DbSet Editions { get; set; } - public DbSet Publishers { get; set; } + public DbSet Books { get; set; } + public DbSet CheckoutRecords { get; set; } + public DbSet Readers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs index eddda42..2ced383 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs @@ -9,7 +9,7 @@ public static void Main() { var book = context.Books.First(); - Console.WriteLine(String.Format("Original Book - {0}: {1}", book.BookId, book.Title)); + Console.WriteLine(String.Format("Original Book - {0}: {1}", book.Id, book.Title)); book.Title = "Frankenstein: or, The Modern Prometheus"; context.SaveChanges(); @@ -19,7 +19,7 @@ public static void Main() var updatedBook = context.Books .Single(b => b.Title.Contains("Frankenstein")); - Console.WriteLine(String.Format("Updated Book - {0}: {1}", updatedBook.BookId, updatedBook.Title)); + Console.WriteLine(String.Format("Updated Book - {0}: {1}", updatedBook.Id, updatedBook.Title)); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md index f1564c3..b90c043 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to update entities to a databa - [LibraryContext.cs](../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs index 64569fa..a72c816 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs @@ -9,7 +9,7 @@ public static void Main() { var untrackedBook = new Book() { - BookId = 1, + Id = 1, Title = "Frankenstein: or, The Modern Prometheus", Genre = "Science Fiction", PublicationYear = 1818 @@ -19,9 +19,9 @@ public static void Main() context.SaveChanges(); var updatedBook = context.Books - .Single(b => b.BookId == 1); + .Single(b => b.Id == 1); - Console.WriteLine("{0}: {1}, {2} {3}", updatedBook.BookId, updatedBook.Title, updatedBook.Genre, updatedBook.PublicationYear); + Console.WriteLine("{0}: {1}, {2} {3}", updatedBook.Id, updatedBook.Title, updatedBook.Genre, updatedBook.PublicationYear); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md index 32880a5..1e52b18 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to update untracked entities i - [LibraryContext.cs](../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/querying/filtering-entities/README.md b/content/efcore/getting-started/samples/querying/filtering-entities/README.md index 420a5f0..4e91fd0 100644 --- a/content/efcore/getting-started/samples/querying/filtering-entities/README.md +++ b/content/efcore/getting-started/samples/querying/filtering-entities/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to query a subset of entities - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/querying/loading-all-entities/README.md b/content/efcore/getting-started/samples/querying/loading-all-entities/README.md index cd06c39..e16c85e 100644 --- a/content/efcore/getting-started/samples/querying/loading-all-entities/README.md +++ b/content/efcore/getting-started/samples/querying/loading-all-entities/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to query all entities from the - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/querying/loading-single-entity/Program.cs b/content/efcore/getting-started/samples/querying/loading-single-entity/Program.cs index c0a1c52..3ebb086 100644 --- a/content/efcore/getting-started/samples/querying/loading-single-entity/Program.cs +++ b/content/efcore/getting-started/samples/querying/loading-single-entity/Program.cs @@ -9,7 +9,7 @@ public static void Main() using (var context = new LibraryContext()) { var book = context.Books - .Single(b => b.BookId == 1); + .Single(b => b.Id == 1); Console.WriteLine(book.Title); } } diff --git a/content/efcore/getting-started/samples/querying/loading-single-entity/README.md b/content/efcore/getting-started/samples/querying/loading-single-entity/README.md index 1080caf..131a4af 100644 --- a/content/efcore/getting-started/samples/querying/loading-single-entity/README.md +++ b/content/efcore/getting-started/samples/querying/loading-single-entity/README.md @@ -7,5 +7,6 @@ This code example demonstrates how to use EF Core to query a single entity from - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) -- [Edition.cs](../../shared/Edition.cs) -- [Publisher.cs](../../shared/Publisher.cs) \ No newline at end of file +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/Address.cs b/content/efcore/getting-started/samples/shared/Address.cs new file mode 100644 index 0000000..8b9a12c --- /dev/null +++ b/content/efcore/getting-started/samples/shared/Address.cs @@ -0,0 +1,6 @@ +public class Address +{ + public int Id { get; set; } + public string City { get; set; } + public string State { get; set; } +} diff --git a/content/efcore/getting-started/samples/shared/Author.cs b/content/efcore/getting-started/samples/shared/Author.cs index 88cc2d8..01bd74b 100644 --- a/content/efcore/getting-started/samples/shared/Author.cs +++ b/content/efcore/getting-started/samples/shared/Author.cs @@ -2,8 +2,9 @@ public class Author { - public int AuthorId { get; set; } + public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } + public List Books { get; set; } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/Book.cs b/content/efcore/getting-started/samples/shared/Book.cs index 59d2071..44324bf 100644 --- a/content/efcore/getting-started/samples/shared/Book.cs +++ b/content/efcore/getting-started/samples/shared/Book.cs @@ -2,10 +2,11 @@ public class Book { - public int BookId { get; set; } + public int Id { get; set; } public string Title { get; set; } public string Genre { get; set; } public int PublicationYear { get; set; } + public Author Author { get; set; } - public List Editions { get; set; } + public List CheckoutRecords { get; set; } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/CheckoutRecord.cs b/content/efcore/getting-started/samples/shared/CheckoutRecord.cs new file mode 100644 index 0000000..b57ec46 --- /dev/null +++ b/content/efcore/getting-started/samples/shared/CheckoutRecord.cs @@ -0,0 +1,12 @@ +using System; + +public class CheckoutRecord +{ + public int Id { get; set; } + public DateTime CheckoutDate { get; set; } + public DateTime ReturnDate { get; set; } + public DateTime DueDate { get; set; } + + public Book Book { get; set; } + public Reader Reader { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/Edition.cs b/content/efcore/getting-started/samples/shared/Edition.cs deleted file mode 100644 index 7543d24..0000000 --- a/content/efcore/getting-started/samples/shared/Edition.cs +++ /dev/null @@ -1,7 +0,0 @@ -public class Edition -{ - public int EditionId { get; set; } - public Book Book { get; set; } - public int Year { get; set; } - public Publisher Publisher { get; set; } -} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/LibraryContext.cs b/content/efcore/getting-started/samples/shared/LibraryContext.cs index 7f4fa9a..4194307 100644 --- a/content/efcore/getting-started/samples/shared/LibraryContext.cs +++ b/content/efcore/getting-started/samples/shared/LibraryContext.cs @@ -3,10 +3,11 @@ public class LibraryContext : DbContext { - public DbSet Books { get; set; } + public DbSet
Addresses { get; set; } public DbSet Authors { get; set; } - public DbSet Editions { get; set; } - public DbSet Publishers { get; set; } + public DbSet Books { get; set; } + public DbSet CheckoutRecords { get; set; } + public DbSet Readers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { diff --git a/content/efcore/getting-started/samples/shared/Publisher.cs b/content/efcore/getting-started/samples/shared/Publisher.cs deleted file mode 100644 index 0a6082f..0000000 --- a/content/efcore/getting-started/samples/shared/Publisher.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Collections.Generic; - -public class Publisher -{ - public int PublisherId { get; set; } - public string Name { get; set; } - public List Editions { get; set; } -} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/Reader.cs b/content/efcore/getting-started/samples/shared/Reader.cs new file mode 100644 index 0000000..94eaedb --- /dev/null +++ b/content/efcore/getting-started/samples/shared/Reader.cs @@ -0,0 +1,8 @@ +public class Reader +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + + public Address Address { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/tutorial-database-reference.md b/content/efcore/getting-started/tutorial-database-reference.md index 6c29fd4..0992080 100644 --- a/content/efcore/getting-started/tutorial-database-reference.md +++ b/content/efcore/getting-started/tutorial-database-reference.md @@ -2,63 +2,61 @@ ## Authors -| AuthorId | FirstName | LastName | -|----------|------------|-----------| -| 1 | Jack | London | -| 2 | Mark | Twain | -| 3 | Willa | Cather | -| 4 | Frederick | Douglass | -| 7 | Agatha | Christie | -| 8 | Virginia | Woolf | -| 9 | Frances | Harper | -| 10 | Stephen | Crane | +Id | FirstName | LastName +-----|------------|--------- +1 | Jack | London +2 | Mark | Twain +3 | Willa | Cather +4 | Frederick | Douglass +7 | Agatha | Christie +8 | Virginia | Woolf +9 | Frances | Harper +10 | Stephen | Crane ## Books -| BookId | AuthorId | Title | Genre | PublicationYear | -|--------|----------|---------------------------------|------------------|-----------------| -| 1 | 9 | Mrs Dalloway | Literary | 1925 | -| 2 | 1 | The Scarlet Plague | Science Fiction | 1912 | -| 3 | 8 | The Secret Adversary | Mystery | 1922 | -| 4 | 5 | My Bondage and My Freedom | Narrative | 1855 | -| 5 | 4 | My Antonia | Historical | 1918 | -| 6 | 4 | O Pioneers! | Historical | 1913 | -| 7 | 2 | Adventures of Huckleberry Finn | Satire | 1884 | -| 8 | 2 | The Adventures of Tom Sawyer | Satire | 1876 | -| 9 | 10 | Iola Leroy | Historical | 1892 | -| 10 | 8 | Murder on the Orient Express | Mystery | 1934 | -| 11 | 1 | The Call of the Wild | Adventure | 1903 | -| 12 | 4 | Death Comes for the Archbishop | Historical | 1927 | +Id | AuthorId | Title | Genre | PublicationYear +-----|----------|---------------------------------|------------------|---------------- +1 | 9 | Mrs Dalloway | Literary | 1925 +2 | 1 | The Scarlet Plague | Science Fiction | 1912 +3 | 8 | The Secret Adversary | Mystery | 1922 +4 | 5 | My Bondage and My Freedom | Narrative | 1855 +5 | 4 | My Antonia | Historical | 1918 +6 | 4 | O Pioneers! | Historical | 1913 +7 | 2 | Adventures of Huckleberry Finn | Satire | 1884 +8 | 2 | The Adventures of Tom Sawyer | Satire | 1876 +9 | 10 | Iola Leroy | Historical | 1892 +10 | 8 | Murder on the Orient Express | Mystery | 1934 +11 | 1 | The Call of the Wild | Adventure | 1903 +12 | 4 | Death Comes for the Archbishop | Historical | 1927 -## Editions +## Checkout Records + +Id | BookId | ReaderId | CheckoutDate | ReturnDate | DueDate +-----|--------|----------|--------------|------------|----------- +1 | 10 | 2 | 12-1-2016 | 12-4-2016 | 12-15-2016 +2 | 4 | 6 | 12-5-2016 | 12-31-2016 | 12-19-2016 +3 | 1 | 3 | 12-5-2016 | 12-19-2016 | 12-19-2016 +4 | 3 | 2 | 12-10-2016 | 12-12-2016 | 12-24-2016 +5 | 10 | 4 | 12-16-2016 | 1-1-2017 | 12-30-2016 + +## Readers + +Id | AddressId | FirstName | LastName +-----|-----------|------------|------------ +1 | 1 | Andrew | Salami +2 | 2 | Rebecca | Dahlman +3 | 3 | Ryan | Helmoski +4 | 4 | Melia | Deakin +5 | 5 | David | Mikhayelyan +6 | 6 | Aryn | Huck + +## Addresses -| EditionId | BookId | PublisherId | Year | -|----------|------------|-----------| --------- | -| 1 | 2 | 2 | 1647 | -| 2 | 2 | 4 | 1656 | -| 3 | 8 | 2 | 2014| -| 4 | 11 | 4 | 2013 | -| 5 | 6 | 5 | 1837 | -| 6 | 1 | 3 | 2000 | -| 7 | 10 | 1 | 1820 | -| 8 | 12 | 5 | 1999 | -| 9 | 3 | 1 | 2012 | -| 10 | 4 | 4 | 1969 | -| 11 | 10 | 1 | 2011 | -| 12 | 7 | 6 | 1974 | -| 13 | 9 | 4 | 2010 | -| 14 | 5 | 2 | 2015 | -| 15 | 2 | 7 | 1929 | - -## Publishers - -| PublisherId | Name | -|----------|------------| -| 1 | HarperCollins Publishers | -| 2 | CreateSpace Independent Publishing Platform | -| 3 | Penguin Books | -| 4 | Dover Publications| -| 5 | University of Nebraska Press| -| 6 | Signet Classics | -| 7 | The Macmillan Company | - \ No newline at end of file +Id | City | State +------|------------|--------- +1 | Springview | Nebraska +2 | Thurston | Nebraska +3 | Austin | Texas +4 | Gurley | Nebraska +5 | Lincoln | Nebraska \ No newline at end of file diff --git a/content/efcore/getting-started/tutorial-model-reference.md b/content/efcore/getting-started/tutorial-model-reference.md index a973ced..d998e79 100644 --- a/content/efcore/getting-started/tutorial-model-reference.md +++ b/content/efcore/getting-started/tutorial-model-reference.md @@ -1,55 +1,76 @@ # Entity Classes -In code, our entity classes look like: +Here is what the entity classes that make up our example data model look like: -## Author +## Author.cs ```{.snippet} +using System.Collections.Generic; + public class Author { -public int AuthorId { get; set; } -public string FirstName { get; set; } -public string LastName { get; set; } + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } -public List Books { get; set; } + public List Books { get; set; } } ``` -## Book +## Book.cs ```{.snippet} +using System.Collections.Generic; + public class Book { -public int BookId { get; set; } -public string Title { get; set; } -public string Genre { get; set; } -public int PublicationYear { get; set; } - -public Author Author { get; set; } + public int Id { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } + + public Author Author { get; set; } + public List CheckoutRecords { get; set; } } ``` -## Edition +## CheckoutRecord.cs ```{.snippet} -public class Edition -{ -public int EditionId { get; set; } -public int Year { get; set; } - -public Book Book { get; set; } -public Publisher Publisher {get; set;} -} +using System; + +public class CheckoutRecord +{ + public int Id { get; set; } + public DateTime CheckoutDate { get; set; } + public DateTime ReturnDate { get; set; } + public DateTime DueDate { get; set; } + + public Book Book { get; set; } + public Reader Reader { get; set; } +} ``` -## Publisher +## Reader.cs ```{.snippet} -public class Publisher -{ -public int PublisherId { get; set; } -public string Name { get; set; } +public class Reader +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + + public Address Address { get; set; } +} +``` + +## Address.cs -public List Editions { get; set; } -} +```{.snippet} +public class Address +{ + public int Id { get; set; } + public string City { get; set; } + public string State { get; set; } +} ``` \ No newline at end of file From f4a9080b389fda0218cccb5c5b45c9d9d2af7a53 Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Mon, 6 Feb 2017 18:57:12 -0600 Subject: [PATCH 30/56] Resolves #49 - Makes the reference pages appendices --- content/efcore/getting-started/README.md | 2 ++ content/efcore/getting-started/toc.md | 2 ++ .../efcore/getting-started/tutorial-database-reference.md | 3 ++- content/efcore/getting-started/tutorial-model-reference.md | 5 ++--- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 8ea0975..98d68bc 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -18,3 +18,5 @@ This tutorial will cover the following topics: - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) - [Manipulating Entities](manipulating-entities.md) +- [Appendix: Data Model Reference](tutorial-model-reference.md) +- [Appendix: Database Reference](tutorial-database-reference.md) diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index 9249c92..3d20bb0 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -3,3 +3,5 @@ - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) - [Manipulating Entities](manipulating-entities.md) +- [Appendix: Data Model Reference](tutorial-model-reference.md) +- [Appendix: Database Reference](tutorial-database-reference.md) diff --git a/content/efcore/getting-started/tutorial-database-reference.md b/content/efcore/getting-started/tutorial-database-reference.md index 0992080..d2a1c35 100644 --- a/content/efcore/getting-started/tutorial-database-reference.md +++ b/content/efcore/getting-started/tutorial-database-reference.md @@ -1,4 +1,5 @@ -# Database Tables +# Database Reference +This document details the data contained within the example database used throughout this tutorial. ## Authors diff --git a/content/efcore/getting-started/tutorial-model-reference.md b/content/efcore/getting-started/tutorial-model-reference.md index d998e79..dfaf0bf 100644 --- a/content/efcore/getting-started/tutorial-model-reference.md +++ b/content/efcore/getting-started/tutorial-model-reference.md @@ -1,7 +1,6 @@ # Entity Classes - -Here is what the entity classes that make up our example data model look like: - +This document contains the entity class definitions for the example data model used throughout this tutorial. + ## Author.cs ```{.snippet} From 20a08faab62a81392eb900feb7ac93f7d3f13f5b Mon Sep 17 00:00:00 2001 From: arynhuck Date: Tue, 7 Feb 2017 16:41:22 -0600 Subject: [PATCH 31/56] Resolves #4 - Understanding Data Models --- content/efcore/getting-started/README.md | 1 + content/efcore/getting-started/toc.md | 1 + .../understanding-data-models.md | 48 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 content/efcore/getting-started/understanding-data-models.md diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 98d68bc..d607299 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -15,6 +15,7 @@ This tutorial will cover the following topics: - [Intro to EF Core](intro-to-ef-core.md) - [Installing EF Core](installing-ef-core.md) +- [Understanding Data Models](understanding-data-models.md) - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) - [Manipulating Entities](manipulating-entities.md) diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index 3d20bb0..eb7cce3 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -1,5 +1,6 @@ - [Intro to EF Core](intro-to-ef-core.md) - [Installing EF Core](installing-ef-core.md) +- [Understanding Data Models](understanding-data-models.md) - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) - [Manipulating Entities](manipulating-entities.md) diff --git a/content/efcore/getting-started/understanding-data-models.md b/content/efcore/getting-started/understanding-data-models.md new file mode 100644 index 0000000..57df089 --- /dev/null +++ b/content/efcore/getting-started/understanding-data-models.md @@ -0,0 +1,48 @@ +# Understanding Data Models + +In this lesson, we are going to learn what a data model is and how to manually define a data model for EF Core. + +## What is a Data Model? + +A data model is a representation of the different types of information within a system and their relationships. For example, in a relational database, the database schema (tables, columns, etc.) would make up the data model. You sometimes hear these data models simply referred to as "models" in EF Core. + +## Defining a Data Model + +In EF Core, a data model is defined using "plain-old" C# object (POCO) classes. These are classes that solely consist of getters and setters. In EF Core, these POCO classes are referred to as **entities** or **entity classes**. + +Let's look at an example. Imagine we are creating a library application. What types of information would be in such a system? Books and readers are two good examples. To include these types of information in our data model, we first define an entity for each of them like so: + +```{C#} +public class Book +{ + public int Id { get; set; } + public string Title { get; set; } + public int PublicationYear { get; set; } +} + +public class Reader +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } +} +``` + +> **NOTE** {.note} +> We will be using this library example throughout the tutorial. It is very simple at the moment, but we will be adding more data members and entities in later lessons to make it more like a full-fledged library application. + +After defining our entities, we next need to register them with EF Core. We do this by first extending the abstract class [DbContext](https://msdn.microsoft.com/library/system.data.entity.dbcontext), which serves as the connection between our C# code and database. Then we add our entities as `DbSet` properties to the context as shown below: + +```{C#} +public class LibraryContext : DbContext +{ + public DbSet Books { get; set; } + public DbSet Readers { get; set; } +} +``` + +Now that we have defined our data model, we can use EF Core to interact with a matching database. It is important that the data model and database schema match because otherwise EF Core won't be able to translate between the two, and it will just throw an error instead. + +When mapping the data model to the database, EF Core makes some assumptions which allow it to perform the mapping automatically. For example, it expects each entity in the data model to correspond to a database table that shares the same name as the `DbSet<>` property in the `DbContext`. In our library example, a matching database would have a "Books" table and a "Readers" table. Likewise, it expects each property of an entity to correspond to a table column that shares the same name and datatype. Thus, the "Books" table in our example would have an "Id" column with a `INT` datatype, a "Title" column with a `VARCHAR` datatype, and a "PublicationYear" column with an `INT` datatype. These assumptions made by EF Core are referred to as **conventions**, and they are simply its default behavior. + +In cases where you don't want the default behavior, conventions can be overridden through two different methods. **Data Annotations** involves annotating your entity classes to specify desired behavior. **Fluent API** is a programmatic method of configuring EF Core, and it overrides data annotations. This tutorial focuses on Fluent API because it supports some features that are not available with data annotations. We will learn more about using Fluent API to configure EF Core in upcoming lessons. \ No newline at end of file From 68393694f3938bff193ce4236112cb44b34deba6 Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Wed, 1 Mar 2017 19:47:03 -0600 Subject: [PATCH 32/56] Resolves #68 - Consistently use bold for terms rather than italics --- content/efcore/getting-started/loading-related-data.md | 2 +- content/efcore/getting-started/manipulating-entities.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/efcore/getting-started/loading-related-data.md b/content/efcore/getting-started/loading-related-data.md index 801497d..bc64612 100644 --- a/content/efcore/getting-started/loading-related-data.md +++ b/content/efcore/getting-started/loading-related-data.md @@ -95,7 +95,7 @@ using (var context = new LibraryContext()) > **Note** {.note} > Explicit Loading support was introduced in EF Core 1.1.0. If you are using an earlier release, the functionality in this section will not be available. -In the previous section, we used *eager loading* which loads the related data from the database as part of the initial database query. Another option is to use *explicit loading* which retrieves the related data separately from the original database query. This allows us to query and filter the related entities before loading them into memory, so we only pull the necessary information from the database. +In the previous section, we used **eager loading** which loads the related data from the database as part of the initial database query. Another option is to use **explicit loading** which retrieves the related data separately from the original database query. This allows us to query and filter the related entities before loading them into memory, so we only pull the necessary information from the database. To use explicit loading, we first use the context's `Entry` method to specify the entity that we want to load related data for. Then, we use the `Collection` and `Reference` methods to specify the related data to load for the entity. `Collection` is used when retrieving multiple items, and `Reference` is used for single items. Finally, we use the `Load` method to actually load the data from the database. diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md index f5da559..ec62376 100644 --- a/content/efcore/getting-started/manipulating-entities.md +++ b/content/efcore/getting-started/manipulating-entities.md @@ -94,7 +94,7 @@ using (var context = new LibraryContext()) :::repl{data-name=updating-entities} ::: -Notice we did not have to tell EF Core that the entity had been changed to update its values. This is because the book we retrieved from the database is a *Tracked Entity*, meaning EF Core will keep track of any changes made to it. EF Core will continue to track changes made to the entity until the context is disposed, which occurs automatically when leaving the `using` block. To learn more about tracked entities, check out the ["Tracking vs. No-Tracking"](https://docs.microsoft.com/en-us/ef/core/querying/tracking) page in the docs. +Notice we did not have to tell EF Core that the entity had been changed to update its values. This is because the book we retrieved from the database is a **tracked entity**, meaning EF Core will keep track of any changes made to it. EF Core will continue to track changes made to the entity until the context is disposed, which occurs automatically when leaving the `using` block. To learn more about tracked entities, check out the ["Tracking vs. No-Tracking"](https://docs.microsoft.com/en-us/ef/core/querying/tracking) page in the docs. Suppose you want to update an untracked entity. As long as the untracked entity has the same primary key as the record in the database, you can accomplish this using the `DbSet`'s `Update` method. In the following example, we update the book with a primary key of `1`: From 6743489d9ab23b528586855072100d60d512b18a Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Mon, 6 Mar 2017 16:49:43 -0600 Subject: [PATCH 33/56] Resolves #74 - Spaces instead of tabs in markdown code examples --- .../getting-started/loading-related-data.md | 40 +++++++++---------- .../understanding-data-models.md | 16 ++++---- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/content/efcore/getting-started/loading-related-data.md b/content/efcore/getting-started/loading-related-data.md index bc64612..198efbf 100644 --- a/content/efcore/getting-started/loading-related-data.md +++ b/content/efcore/getting-started/loading-related-data.md @@ -10,8 +10,8 @@ When loading an entity from the database, EF Core will automatically include pro ```{.snippet} using (var context = new LibraryContext()) { - var book = context.Books - .Single(b => b.Id == 1); + var book = context.Books + .Single(b => b.Id == 1); } ``` :::repl{data-name=field-not-included} @@ -22,9 +22,9 @@ We need to explicitly tell EF Core if we want to load a non-primitive type like ```{.snippet} using (var context = new LibraryContext()) { - var book = context.Books - .Include(b => b.Author) - .Single(b => b.Id == 1); + var book = context.Books + .Include(b => b.Author) + .Single(b => b.Id == 1); } ``` :::repl{data-name=include-method} @@ -35,10 +35,10 @@ You can also include multiple non-primitive type properties at once by calling t ```{.snippet} using (var context = new LibraryContext()) { - var book = context.Books - .Include(b => b.CheckoutRecords) - .Include(b => b.Author) - .Single(b => b.Id == 1); + var book = context.Books + .Include(b => b.CheckoutRecords) + .Include(b => b.Author) + .Single(b => b.Id == 1); } ``` :::repl{data-name=multiple-include-methods} @@ -51,10 +51,10 @@ Now, what happens if one of the properties we include also has non-primitive typ ```{.snippet} using (var context = new LibraryContext()) { - var book = context.Book - .Include(b => b.CheckoutRecords) - .ThenInclude(c => c.Reader) - .Single(b => b.Id == 1); + var book = context.Book + .Include(b => b.CheckoutRecords) + .ThenInclude(c => c.Reader) + .Single(b => b.Id == 1); } ``` :::repl{data-name=then-include-method} @@ -65,11 +65,11 @@ We can also chain `ThenInclude` calls to include deeper layers of related data. ```{.snippet} using (var context = new LibraryContext()) { - var author = context.Authors - .Include(a => a.Books) - .ThenInclude(b => b.CheckoutRecords) - .ThenInclude(c => c.Reader) - .Single(a => a.LastName == "Douglass"); + var author = context.Authors + .Include(a => a.Books) + .ThenInclude(b => b.CheckoutRecords) + .ThenInclude(c => c.Reader) + .Single(a => a.LastName == "Douglass"); } ``` :::repl{data-name=then-include-method-chain} @@ -80,7 +80,7 @@ A mix of `Include` and `ThenInclude` commands can also be chained together to in ```{.snippet} using (var context = new LibraryContext()) { - var book = context.Books + var book = context.Books .Include(c => c.CheckoutRecords) .ThenInclude(r => r.Reader) .Include(b => b.Author) @@ -163,7 +163,7 @@ using (var context = new LibraryContext()) .Single(b => b.Title.Contains("Orient Express")); var mostRecentCheckout = context.Entry(book) - .Collection(b => b.CheckoutRecords) + .Collection(b => b.CheckoutRecords) .Query() .Max(c => c.CheckoutDate); } diff --git a/content/efcore/getting-started/understanding-data-models.md b/content/efcore/getting-started/understanding-data-models.md index 57df089..8b3c85f 100644 --- a/content/efcore/getting-started/understanding-data-models.md +++ b/content/efcore/getting-started/understanding-data-models.md @@ -15,16 +15,16 @@ Let's look at an example. Imagine we are creating a library application. What ty ```{C#} public class Book { - public int Id { get; set; } - public string Title { get; set; } - public int PublicationYear { get; set; } + public int Id { get; set; } + public string Title { get; set; } + public int PublicationYear { get; set; } } public class Reader { - public int Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } } ``` @@ -36,8 +36,8 @@ After defining our entities, we next need to register them with EF Core. We do t ```{C#} public class LibraryContext : DbContext { - public DbSet Books { get; set; } - public DbSet Readers { get; set; } + public DbSet Books { get; set; } + public DbSet Readers { get; set; } } ``` From d68373ee10eccd0f91faa489f651606166a9dbc3 Mon Sep 17 00:00:00 2001 From: deakgeek Date: Mon, 6 Mar 2017 17:28:08 -0600 Subject: [PATCH 34/56] Resolves #5 - Defining Unique Identifiers --- content/efcore/getting-started/README.md | 1 + .../defining-unique-identifiers.md | 63 +++++++++++++++++++ .../composite-key/Book.cs | 11 ++++ .../composite-key/CheckoutRecord.cs | 14 +++++ .../composite-key/LibraryContext.cs | 20 ++++++ .../composite-key/Program.cs | 14 +++++ .../composite-key/README.md | 10 +++ .../composite-key/Reader.cs | 10 +++ .../primary-key/Book.cs | 10 +++ .../primary-key/LibraryContext.cs | 13 ++++ .../primary-key/Program.cs | 14 +++++ .../primary-key/README.md | 8 +++ .../unconventional-key-name/Book.cs | 9 +++ .../unconventional-key-name/LibraryContext.cs | 18 ++++++ .../unconventional-key-name/Program.cs | 14 +++++ .../unconventional-key-name/README.md | 8 +++ .../getting-started/samples/shared/Reader.cs | 3 + content/efcore/getting-started/toc.md | 1 + 18 files changed, 241 insertions(+) create mode 100644 content/efcore/getting-started/defining-unique-identifiers.md create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Book.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/CheckoutRecord.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/LibraryContext.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Program.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/README.md create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Reader.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/Book.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/LibraryContext.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/Program.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/README.md create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/Book.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/LibraryContext.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/Program.cs create mode 100644 content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/README.md diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index d607299..a47b67f 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -16,6 +16,7 @@ This tutorial will cover the following topics: - [Intro to EF Core](intro-to-ef-core.md) - [Installing EF Core](installing-ef-core.md) - [Understanding Data Models](understanding-data-models.md) +- [Defining Unique Identifiers](defining-unique-identifiers.md) - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) - [Manipulating Entities](manipulating-entities.md) diff --git a/content/efcore/getting-started/defining-unique-identifiers.md b/content/efcore/getting-started/defining-unique-identifiers.md new file mode 100644 index 0000000..af2af1f --- /dev/null +++ b/content/efcore/getting-started/defining-unique-identifiers.md @@ -0,0 +1,63 @@ +# Defining Unique Identifiers + +In this lesson we will learn about unique identifiers, how they are configured by default in EF Core, and how to manually configure them when we don't follow the convention. + +## Primary Keys + +When defining our data model, we need to ensure that each entity class includes a property that can be used to uniquely identify instances of that entity. These unique identifiers are referred to as **primary keys**, and they map to the concept of primary keys in a relational database. + +By convention, EF Core assumes that a property named `Id` or `Id` is the primary key for an entity. For example, in our `Book` class below, the property named `Id` is assumed to be the primary key. + +```{.snippet} +public class Book +{ + public int Id { get; set; } // You could also use 'BookId' here + public int ISBN { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } +} +``` +:::repl{data-name=primary-key} +::: + +## Unconventionally Named Keys + +In some cases, you may not want to use the conventional naming scheme for your primary key. For example, all commercially-sold books have a unique ISBN, so we could use that as a unique identifier instead of adding an extra `Id` property (assuming our library doesn't contain multiple copies of the same book). To configure an unconventionally named key like `ISBN`, use the Fluent API `HasKey` method, as shown below: + +```{.snippet} + +public class LibraryContext : DbContext +{ + public DbSet Books { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) { + modelBuilder.Entity() + .HasKey(b => b.ISBN); + } +} + +``` +:::repl{data-name=unconventional-key-name} +::: + +## Composite Keys + +Instead of adding a property to an entity solely for the purpose of uniquely identifying it, you may be able to use a combination of its existing properties. For example, in our library data model we added an `Id` property to `CheckoutRecord`, but a book can't be checked out by multiple readers at the same time, so we could use its `ReaderId`, `BookId`, and `CheckoutDate` properties to uniquely identify it instead. Combining multiple properties as a unique identifier like this is known as a **composite key**. + +To configure a composite key, we use Fluent API's `HasKey` method. In the following example, we configure a composite key for `CheckoutRecord` based on its `CheckoutDate` and its foreign keys `ReaderId` and `BookId`. + +```{.snippet} +public class LibraryContext : DbContext +{ + public DbSet CheckoutRecords { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) { + modelBuilder.Entity() + .HasKey(b => new { cr.ReaderId, cr.BookId, cr.CheckoutDate }); + } +} + +``` +:::repl{data-name=composite-key} +::: \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Book.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Book.cs new file mode 100644 index 0000000..ef84fe5 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Book.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +public class Book +{ + public int Id { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } + + public List CheckoutRecords { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/CheckoutRecord.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/CheckoutRecord.cs new file mode 100644 index 0000000..4a9665f --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/CheckoutRecord.cs @@ -0,0 +1,14 @@ +using System; + +public class CheckoutRecord +{ + public int Id { get; set; } + public DateTime CheckoutDate { get; set; } + public DateTime ReturnDate { get; set; } + public DateTime DueDate { get; set; } + + public int BookId { get; set; } + public int ReaderId { get; set; } + public Book Book { get; set; } + public Reader Reader { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/LibraryContext.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/LibraryContext.cs new file mode 100644 index 0000000..b39b6be --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/LibraryContext.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore; +using REPLHelper; + +public class LibraryContext : DbContext +{ + public DbSet CheckoutRecords { get; set; } + public DbSet Books { get; set; } + public DbSet Readers { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasKey(cr => new { cr.ReaderId, cr.BookId, cr.CheckoutDate }); + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite(DBHelper.GetMigrationDbConnectionString()); + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Program.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Program.cs new file mode 100644 index 0000000..2289a79 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Program.cs @@ -0,0 +1,14 @@ +using System; +using System.Linq; +using REPLHelper; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + DBHelper.PrintDatabaseSchema(context); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/README.md b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/README.md new file mode 100644 index 0000000..11fddf2 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/README.md @@ -0,0 +1,10 @@ +# Composite Key + +This code example demonstrates how to configure a composite key in EF Core via Fluent API. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [CheckoutRecord.cs](CheckoutRecord.cs) +- [Book.cs](Book.cs) +- [Reader.cs](Reader.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Reader.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Reader.cs new file mode 100644 index 0000000..a74da8e --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/Reader.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +public class Reader +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + + public List CheckoutRecords { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/Book.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/Book.cs new file mode 100644 index 0000000..0db12f6 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/Book.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +public class Book +{ + public int Id { get; set; } // You could also use 'BookId' here + public int ISBN { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/LibraryContext.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/LibraryContext.cs new file mode 100644 index 0000000..9e6b657 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/LibraryContext.cs @@ -0,0 +1,13 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using REPLHelper; + +public class LibraryContext : DbContext +{ + public DbSet Books { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite(DBHelper.GetMigrationDbConnectionString()); + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/Program.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/Program.cs new file mode 100644 index 0000000..2289a79 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/Program.cs @@ -0,0 +1,14 @@ +using System; +using System.Linq; +using REPLHelper; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + DBHelper.PrintDatabaseSchema(context); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/README.md b/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/README.md new file mode 100644 index 0000000..026ee02 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/README.md @@ -0,0 +1,8 @@ +# Primary Key + +This code example demonstrates how primary keys work in EF Core by convention. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [Book.cs](Book.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/Book.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/Book.cs new file mode 100644 index 0000000..4a12e34 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/Book.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +public class Book +{ + public int ISBN { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/LibraryContext.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/LibraryContext.cs new file mode 100644 index 0000000..bef9c27 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/LibraryContext.cs @@ -0,0 +1,18 @@ +using Microsoft.EntityFrameworkCore; +using REPLHelper; + +public class LibraryContext : DbContext +{ + public DbSet Books { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasKey(b => b.ISBN); + } + +protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite(DBHelper.GetMigrationDbConnectionString()); + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/Program.cs b/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/Program.cs new file mode 100644 index 0000000..2289a79 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/Program.cs @@ -0,0 +1,14 @@ +using System; +using System.Linq; +using REPLHelper; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + DBHelper.PrintDatabaseSchema(context); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/README.md b/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/README.md new file mode 100644 index 0000000..87fce9e --- /dev/null +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/README.md @@ -0,0 +1,8 @@ +# Unconventional Key Name + +This code example demonstrates how to set an unconventionally-named property as the primary key in EF Core via Fluent API. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [Book.cs](Book.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/shared/Reader.cs b/content/efcore/getting-started/samples/shared/Reader.cs index 94eaedb..9f907e4 100644 --- a/content/efcore/getting-started/samples/shared/Reader.cs +++ b/content/efcore/getting-started/samples/shared/Reader.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; + public class Reader { public int Id { get; set; } @@ -5,4 +7,5 @@ public class Reader public string LastName { get; set; } public Address Address { get; set; } + public List CheckoutRecords { get; set; } } \ No newline at end of file diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index eb7cce3..20504f7 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -1,6 +1,7 @@ - [Intro to EF Core](intro-to-ef-core.md) - [Installing EF Core](installing-ef-core.md) - [Understanding Data Models](understanding-data-models.md) +- [Defining Unique Identifiers](defining-unique-identifiers.md) - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) - [Manipulating Entities](manipulating-entities.md) From 9856e2ad0cb4167033a1af0ed8b0bcdab1e4563a Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Mon, 6 Mar 2017 19:54:56 -0600 Subject: [PATCH 35/56] Resolves #76 - Consistent note formatting --- content/efcore/getting-started/loading-related-data.md | 4 ++-- content/efcore/getting-started/manipulating-entities.md | 4 ++-- content/efcore/getting-started/querying.md | 2 +- content/efcore/getting-started/understanding-data-models.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/content/efcore/getting-started/loading-related-data.md b/content/efcore/getting-started/loading-related-data.md index 198efbf..beb5eb1 100644 --- a/content/efcore/getting-started/loading-related-data.md +++ b/content/efcore/getting-started/loading-related-data.md @@ -1,6 +1,6 @@ # Loading Related Data -> **Note** {.note} +> **Note** {.note} > If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](tutorial-database-reference.md) and [Model Reference](tutorial-model-reference.md) pages. ## Single Layer Inclusion @@ -92,7 +92,7 @@ using (var context = new LibraryContext()) ## Explicit Loading -> **Note** {.note} +> **Note** {.note} > Explicit Loading support was introduced in EF Core 1.1.0. If you are using an earlier release, the functionality in this section will not be available. In the previous section, we used **eager loading** which loads the related data from the database as part of the initial database query. Another option is to use **explicit loading** which retrieves the related data separately from the original database query. This allows us to query and filter the related entities before loading them into memory, so we only pull the necessary information from the database. diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md index ec62376..8127a86 100644 --- a/content/efcore/getting-started/manipulating-entities.md +++ b/content/efcore/getting-started/manipulating-entities.md @@ -2,7 +2,7 @@ Four operations that we often perform on a record in a database are create, read, update, and delete (commonly referred to as "CRUD" operations). We walked through how to read records from a database in the [Querying Data](querying.md) tutorial. Now let's learn how to perform the other CRUD operations which allow us to manipulate records in the database. -> **Note** {.note} +> **Note** {.note} > If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](tutorial-database-reference.md) and [Model Reference](tutorial-model-reference.md) pages. ## Adding Entities to a Database @@ -134,5 +134,5 @@ using (var context = new LibraryContext()) In the previous example, we were able to successfully delete a book, but what happened to that book's checkout records? The short answer is it depends. The way that EF Core handles deletion of an entity with related data depends on several factors including whether the related data is tracked, how EF Core is configured, and how the database is configured. To learn more about the available behaviors and how to configure a certain behavior, check out the [Cascade Delete]() lesson. -> **Note** {.note} +> **Note** {.note} > The Cascade Delete lesson has not been added yet. For now, please refer to the [Cascade Delete](https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete) page in the docs. diff --git a/content/efcore/getting-started/querying.md b/content/efcore/getting-started/querying.md index e64aec1..ef2a81d 100644 --- a/content/efcore/getting-started/querying.md +++ b/content/efcore/getting-started/querying.md @@ -2,7 +2,7 @@ In this lesson, you'll learn how to use querying to fetch one or more items from your database. EF Core uses LINQ to query data, so it is important that you understand LINQ before going through this lesson. Check out the [LINQ lesson](../../csharp/getting-started/linq.md) in the C# Interactive Tutorial if you need a refresher. -> **Note** {.note} +> **Note** {.note} > If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](tutorial-database-reference.md) and [Model Reference](tutorial-model-reference.md) pages. ## Loading All Entities diff --git a/content/efcore/getting-started/understanding-data-models.md b/content/efcore/getting-started/understanding-data-models.md index 8b3c85f..0cf13c0 100644 --- a/content/efcore/getting-started/understanding-data-models.md +++ b/content/efcore/getting-started/understanding-data-models.md @@ -28,7 +28,7 @@ public class Reader } ``` -> **NOTE** {.note} +> **Note** {.note} > We will be using this library example throughout the tutorial. It is very simple at the moment, but we will be adding more data members and entities in later lessons to make it more like a full-fledged library application. After defining our entities, we next need to register them with EF Core. We do this by first extending the abstract class [DbContext](https://msdn.microsoft.com/library/system.data.entity.dbcontext), which serves as the connection between our C# code and database. Then we add our entities as `DbSet` properties to the context as shown below: From f46f064f2bf43cf902a80cdd37738fb702b6ff27 Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Mon, 6 Mar 2017 19:59:48 -0600 Subject: [PATCH 36/56] Resolves #72 - Removes show me buttons from entity class refererence page --- .../efcore/getting-started/tutorial-model-reference.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/efcore/getting-started/tutorial-model-reference.md b/content/efcore/getting-started/tutorial-model-reference.md index dfaf0bf..a4ef580 100644 --- a/content/efcore/getting-started/tutorial-model-reference.md +++ b/content/efcore/getting-started/tutorial-model-reference.md @@ -3,7 +3,7 @@ This document contains the entity class definitions for the example data model u ## Author.cs -```{.snippet} +```c# using System.Collections.Generic; public class Author @@ -18,7 +18,7 @@ public class Author ## Book.cs -```{.snippet} +```c# using System.Collections.Generic; public class Book @@ -35,7 +35,7 @@ public class Book ## CheckoutRecord.cs -```{.snippet} +```c# using System; public class CheckoutRecord @@ -52,7 +52,7 @@ public class CheckoutRecord ## Reader.cs -```{.snippet} +```c# public class Reader { public int Id { get; set; } @@ -65,7 +65,7 @@ public class Reader ## Address.cs -```{.snippet} +```c# public class Address { public int Id { get; set; } From fd1be56b3ab88ae1cb6be9dbfa96dfc82d66b31d Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Mon, 6 Mar 2017 20:02:23 -0600 Subject: [PATCH 37/56] Resolves #70 - Consistent inline code formatting --- content/efcore/getting-started/loading-related-data.md | 4 ++-- content/efcore/getting-started/manipulating-entities.md | 2 +- content/efcore/getting-started/querying.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/efcore/getting-started/loading-related-data.md b/content/efcore/getting-started/loading-related-data.md index beb5eb1..7f00b07 100644 --- a/content/efcore/getting-started/loading-related-data.md +++ b/content/efcore/getting-started/loading-related-data.md @@ -17,7 +17,7 @@ using (var context = new LibraryContext()) :::repl{data-name=field-not-included} ::: -We need to explicitly tell EF Core if we want to load a non-primitive type like the Author field. We do this using the `Include` method. In the example below, the book that is returned will include its author's information. +We need to explicitly tell EF Core if we want to load a non-primitive type like the `Author` field. We do this using the `Include` method. In the example below, the `Book` that is returned will include its `Author` information. ```{.snippet} using (var context = new LibraryContext()) @@ -137,7 +137,7 @@ By using explicit loading, we were able to load only the book we want (_Adventur ### Aggregate Functions -When using explicit loading, we can also use aggregate functions, such as count, max, min, and sum, which allow us to perform calculations on the data without loading it all into memory. The following example counts how many books in the library are by Willa Cather without having to load all of the books into memory: +When using explicit loading, we can also use aggregate functions, such as `Count`, `Max`, `Min`, and `Sum`, which allow us to perform calculations on the data without loading it all into memory. The following example counts how many books in the library are by Willa Cather without having to load all of the books into memory: ```{.snippet} using (var context = new LibraryContext()) diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md index 8127a86..b35c9ef 100644 --- a/content/efcore/getting-started/manipulating-entities.md +++ b/content/efcore/getting-started/manipulating-entities.md @@ -7,7 +7,7 @@ Four operations that we often perform on a record in a database are create, read ## Adding Entities to a Database -Let's first look at how to create a new record in the database. In the following example, we create a new author and add it to the database: +Let's first look at how to create a new record in the database. In the following example, we create a new `Author` and add it to the database: ```{.snippet} using (var context = new LibraryContext()) diff --git a/content/efcore/getting-started/querying.md b/content/efcore/getting-started/querying.md index ef2a81d..5f92385 100644 --- a/content/efcore/getting-started/querying.md +++ b/content/efcore/getting-started/querying.md @@ -57,4 +57,4 @@ using (var context = new LibraryContext()) :::repl{data-name=loading-single-entity} ::: -In this example, we use the `Single` extension method to find the book with an `Id` of 1. Note that we do not need to call `ToList()` because `Single` returns a single entity. It is important to only use `Single` with unique identifiers because if multiple entities meet the success criteria a `System.InvalidOperationException` will be thrown. +In this example, we use the `Single` extension method to find the book with an `Id` of 1. Note that we do not need to call `ToList` because `Single` returns a single entity. It is important to only use `Single` with unique identifiers because if multiple entities meet the success criteria a `System.InvalidOperationException` will be thrown. From b51e47c12a0f9744e8e96f23aa16ebb32cab67db Mon Sep 17 00:00:00 2001 From: deakgeek Date: Tue, 7 Mar 2017 16:14:11 -0600 Subject: [PATCH 38/56] Resolves #78 - Adds missing lesson intros --- content/efcore/getting-started/loading-related-data.md | 4 +++- content/efcore/getting-started/manipulating-entities.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/content/efcore/getting-started/loading-related-data.md b/content/efcore/getting-started/loading-related-data.md index 7f00b07..fa22c0e 100644 --- a/content/efcore/getting-started/loading-related-data.md +++ b/content/efcore/getting-started/loading-related-data.md @@ -1,4 +1,6 @@ -# Loading Related Data +# Loading Related Data + +In this lesson, we will cover how to load non-primitive types from the database using both eager loading and explicit loading, as well as how to use aggregate functions to perform calculations on our data without loading it from the database. > **Note** {.note} > If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](tutorial-database-reference.md) and [Model Reference](tutorial-model-reference.md) pages. diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md index b35c9ef..e221ca7 100644 --- a/content/efcore/getting-started/manipulating-entities.md +++ b/content/efcore/getting-started/manipulating-entities.md @@ -1,6 +1,6 @@ # Manipulating Entities -Four operations that we often perform on a record in a database are create, read, update, and delete (commonly referred to as "CRUD" operations). We walked through how to read records from a database in the [Querying Data](querying.md) tutorial. Now let's learn how to perform the other CRUD operations which allow us to manipulate records in the database. +Four operations that we often perform on a record in a database are create, read, update, and delete (commonly referred to as "CRUD" operations). We walked through how to read records from a database in the [Querying Data](querying.md) lesson. In this lesson, we'll learn how to perform the other CRUD operations which allow us to manipulate records in the database. > **Note** {.note} > If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](tutorial-database-reference.md) and [Model Reference](tutorial-model-reference.md) pages. From 8d0bf9f922582f57cef94899179f0ce4190b9563 Mon Sep 17 00:00:00 2001 From: arynhuck Date: Wed, 8 Mar 2017 19:27:49 -0600 Subject: [PATCH 39/56] Resolves #2 - Generating Databases and Data Models --- content/efcore/getting-started/README.md | 1 + .../generating-databases-and-data-models.md | 65 +++++++++++++++++++ .../generate-database/Book.cs | 7 ++ .../generate-database/LibraryContext.cs | 13 ++++ .../generate-database/Program.cs | 14 ++++ .../generate-database/README.md | 9 +++ .../generate-database/Reader.cs | 6 ++ content/efcore/getting-started/toc.md | 1 + 8 files changed, 116 insertions(+) create mode 100644 content/efcore/getting-started/generating-databases-and-data-models.md create mode 100644 content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Book.cs create mode 100644 content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/LibraryContext.cs create mode 100644 content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Program.cs create mode 100644 content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/README.md create mode 100644 content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Reader.cs diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index a47b67f..fc1b25d 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -16,6 +16,7 @@ This tutorial will cover the following topics: - [Intro to EF Core](intro-to-ef-core.md) - [Installing EF Core](installing-ef-core.md) - [Understanding Data Models](understanding-data-models.md) +- [Generating Databases and Data Models](generating-databases-and-data-models.md) - [Defining Unique Identifiers](defining-unique-identifiers.md) - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) diff --git a/content/efcore/getting-started/generating-databases-and-data-models.md b/content/efcore/getting-started/generating-databases-and-data-models.md new file mode 100644 index 0000000..f13e91c --- /dev/null +++ b/content/efcore/getting-started/generating-databases-and-data-models.md @@ -0,0 +1,65 @@ +# Generating Databases and Data Models + +In this lesson, we will learn how to generate a database from a data model, modify an existing database, and generate a data model from an existing database. + +## Generating a Database from a Data Model + +We can generate a new database that exactly matches our data model using EF Core **migrations**. Migrations are a feature in the EF Core command line tools which take a data model as input and generate database-creation code as output. The resulting code can then be applied to create a new database. + +Let's say we want to generate a database from our library example, we would first navigate to that project's directory from the command line. Then we would run the [dotnet-ef-migrations-add](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#dotnet-ef-migrations-add) command to generate the database-creation code: + +``` +dotnet ef migrations add [migration name] +``` + +> **Note** {.note} +> If the above command fails with the error message, `No executable found matching command "dotnet-ef"`, make sure `Microsoft.EntityFrameworkCore.Tools` has been installed for your project, as shown in the [Installing EF Core](installing-ef-core.md) lesson. Also ensure you are running the command from the directory that contains your `project.json` file. + +Finally, we would run the [dotnet-ef-database-update](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#dotnet-ef-database-update) command to execute the database-creation code. + +``` +dotnet ef migrations update +``` + +After running the above command, we will have a new database that exactly matches our data model. You can run the example below to see what the resulting database schema would look like. It runs the migration commands for you in the cloud so you can test your model in-browser. + +```{.snippet} +public class Book { + public int Id { get; set; } + public string Title { get; set; } + public int PublicationYear { get; set; } +} + +public class Reader { + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } +} +``` +:::repl{data-name=generate-database} +::: + +## Modifying an Existing Database + +If we ever need to make changes to our data model in the future, migrations can also be used to modify our database. To do this, we first update our entity classes; then, we use the same migration commands we used to originally create the database, but with a new migration name. + +``` +dotnet ef migrations add [migration name] +dotnet ef migrations update +``` + +Anytime we make changes to the data model, we will need to add and run a new migration for the changes to be reflected in our database. + +## Generating a Data Model from an Existing Database + +We can also have EF Core automatically generate a data model from an existing database. First, we create an EF Core project by following the steps in the [Installing EF Core](installing-ef-core.md) lesson. Once the project is ready-to-go, we navigate to the directory that contains the `project.json` file in command line. Next, we run the [dotnet-ef-dbcontext-scaffold](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#dotnet-ef-dbcontext-scaffold) command to create a model from the existing database. + +``` +dotnet ef dbcontext scaffold +``` + +For example, if we wanted to generate a data model from an existing SQLite database, we would run the following command: + +``` +dotnet ef dbcontext scaffold Filename=MyDatabase.db Microsoft.EntityFramework.Sqlite +``` \ No newline at end of file diff --git a/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Book.cs b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Book.cs new file mode 100644 index 0000000..1dd4f07 --- /dev/null +++ b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Book.cs @@ -0,0 +1,7 @@ +public class Book +{ + public int Id { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/LibraryContext.cs b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/LibraryContext.cs new file mode 100644 index 0000000..777ca1d --- /dev/null +++ b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/LibraryContext.cs @@ -0,0 +1,13 @@ +using Microsoft.EntityFrameworkCore; +using REPLHelper; + +public class LibraryContext : DbContext +{ + public DbSet Books { get; set; } + public DbSet Readers { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite(DBHelper.GetMigrationDbConnectionString()); + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Program.cs b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Program.cs new file mode 100644 index 0000000..2289a79 --- /dev/null +++ b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Program.cs @@ -0,0 +1,14 @@ +using System; +using System.Linq; +using REPLHelper; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + DBHelper.PrintDatabaseSchema(context); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/README.md b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/README.md new file mode 100644 index 0000000..222a6c9 --- /dev/null +++ b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/README.md @@ -0,0 +1,9 @@ +# Generating from Code + +This code example demonstrates how to generate a database from a data model and print its resulting schema through `REPLService`. + +## Code Files: +- [Program.cs](Program.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [Book.cs](Book.cs) +- [Reader.cs](Reader.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Reader.cs b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Reader.cs new file mode 100644 index 0000000..d435aa6 --- /dev/null +++ b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/Reader.cs @@ -0,0 +1,6 @@ +public class Reader +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index 20504f7..67fb790 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -1,6 +1,7 @@ - [Intro to EF Core](intro-to-ef-core.md) - [Installing EF Core](installing-ef-core.md) - [Understanding Data Models](understanding-data-models.md) +- [Generating Databases and Data Models](generating-databases-and-data-models.md) - [Defining Unique Identifiers](defining-unique-identifiers.md) - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) From 8e77c498dfcec489666919efdd2bd6d802db6616 Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Wed, 8 Mar 2017 19:44:08 -0600 Subject: [PATCH 40/56] Resolves #8 - Defining Entity Relationships --- content/efcore/getting-started/README.md | 1 + .../defining-entity-relationships.md | 139 ++++++++++++++++++ .../many-to-many-relationship/Book.cs | 11 ++ .../LibraryContext.cs | 15 ++ .../many-to-many-relationship/README.md | 10 ++ .../many-to-many-relationship/Reader.cs | 10 ++ .../one-to-many-relationship/Book.cs | 9 ++ .../LibraryContext.cs | 14 ++ .../one-to-many-relationship/README.md | 9 ++ .../LibraryContext.cs | 22 +++ .../one-to-one-manual-foreign-key/README.md | 9 ++ .../one-to-one-relationship/LibraryContext.cs | 14 ++ .../one-to-one-relationship/README.md | 9 ++ .../shared/Address.cs | 9 ++ .../shared/Program.cs | 14 ++ .../shared/Reader.cs | 8 + content/efcore/getting-started/toc.md | 1 + 17 files changed, 304 insertions(+) create mode 100644 content/efcore/getting-started/defining-entity-relationships.md create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/Book.cs create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/LibraryContext.cs create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/README.md create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/Reader.cs create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/Book.cs create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/LibraryContext.cs create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/README.md create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/LibraryContext.cs create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/LibraryContext.cs create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/shared/Address.cs create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/shared/Program.cs create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/shared/Reader.cs diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index fc1b25d..9514b57 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -18,6 +18,7 @@ This tutorial will cover the following topics: - [Understanding Data Models](understanding-data-models.md) - [Generating Databases and Data Models](generating-databases-and-data-models.md) - [Defining Unique Identifiers](defining-unique-identifiers.md) +- [Defining Entity Relationships](defining-entity-relationships.md) - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) - [Manipulating Entities](manipulating-entities.md) diff --git a/content/efcore/getting-started/defining-entity-relationships.md b/content/efcore/getting-started/defining-entity-relationships.md new file mode 100644 index 0000000..538cba9 --- /dev/null +++ b/content/efcore/getting-started/defining-entity-relationships.md @@ -0,0 +1,139 @@ +# Defining Entity Relationships + +In this lesson, we are going to learn what relationships are and how to define them in EF Core. + +## What is a relationship? + +A relationship represents how two entities within a model associate with each other. There are three types of relationships: + + * A **one-to-one** relationship exists when two entities are related to at most one instance of the other entity. In our library example, a reader is related to one address, and an address is related to one reader. + * A **one-to-many** relationship exists when one entity is related to at most one instance of another entity, but the second entity can be related to multiple instances of the first entity. For example, a book has a single author, but an author can have multiple books. + * A **many-to-many** relationship exists when two entities can both be related to multiple instances of the other entity. For example, a reader can check out multiple books, and a book can be checked out by multiple readers over time. + +## Defining Relationships + +Let's learn how to define each type of relationship in EF Core. + +### One-to-One Relationships + + In the following example, we define a one-to-one relationship between `Reader` and `Address`. + +```{.snippet} +public class Reader +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + + public Address Address { get; set; } +} + +public class Address +{ + public int Id { get; set; } + public string City { get; set; } + public string State { get; set; } + + public int ReaderId { get; set; } + public Reader Reader { get; set; } +} +``` +:::repl{data-name=one-to-one-relationship} +::: + +As you can see, we added a property with an `Address` data type to `Reader` and a property with a `Reader` data type to `Address`. Adding a property with another entity class as the data type like this signifies a relationship. The property itself is known as a **navigation property**. + +Defining a navigation property for both of the entities involved in a relationship is known as a **fully defined relationship**. This is generally considered good practice, but it is not necessary. Defining a navigation property for just one of the entities is enough for EF Core to discover the relationship by convention. + +In addition to the navigation properties, we also added a `ReaderId` property to `Address` to track the primary key of the related `Reader`. This is referred to as a **foreign key** property, and it lets EF Core know that the "Addresses" database table should have a foreign key that points to the "Readers" database table. Because `Address` has the foreign key property and is thereby dependent on `Reader`, it is referred to as the **dependent entity** in this relationship, and `Reader` is referred to as the **principal entity**. + +In cases where you don't follow the convention, you will need to manually define which entity is the principal entity and which is the dependent entity using Fluent API. Some specific cases include using a foreign key that doesn't match the principal entity's primary key name, using a foreign key that points to a composite primary key, or including a foreign key in both of the entities involved in the one-to-one relationship. In the following example, both entities include a foreign key, so we define the one-to-one relationship using Fluent API's `HasOne` and `WithOne` methods and then define `Address` as the dependent entity by specifying its foreign key using the `HasForeignKey` method. + +```{.snippet} +public class LibraryContext : DbContext +{ + public DbSet
Addresses { get; set; } + public DbSet Readers { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasOne(r => r.Address) + .WithOne(a => a.Reader) + .HasForeignKey
(a => a.ReaderId); + } +} +``` +:::repl{data-name=one-to-one-manual-foreign-key} +::: + +### One-to-Many Relationships + + In this example, we define a one-to-many relationship between `Author` and `Book`. + +```{.snippet} +public class Author +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + + public List Books { get; set; } +} + +public class Book +{ + public int Id { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } + + public Author Author { get; set; } +} +``` +:::repl{data-name=one-to-many-relationship} +::: + +This time we added a navigation property with an `Author` data type to `Book` and a navigation property with a `List` data type to `Author`. When the navigation property is represented as a collection, such as a list, as opposed to a single entity, the navigation property is referred to as a **collection navigation property**. Unlike one-to-one relationships, EF Core is easily able to identify which entity is the primary entity and which is the dependent entity because it assumes the entity that represents the 'many' side of the relationship is the dependent entity. + +### Many-to-Many Relationships + +In this example, we define a many-to-many relationship between `Reader` and `Book`. + +```{.snippet} +public class Reader +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + + public List CheckoutRecords { get; set; } +} + +public class Book +{ + public int Id { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } + + public List CheckoutRecords { get; set; } +} + +public class CheckoutRecord +{ + public int Id { get; set; } + public DateTime CheckoutDate { get; set; } + public DateTime ReturnDate { get; set; } + public DateTime DueDate { get; set; } + + public Book Book { get; set; } + public Reader Reader { get; set; } +} +``` +:::repl{data-name=many-to-many-relationship} +::: + +Above, we created a one-to-many relationship between `Reader` and `CheckoutRecord` and another one-to-many relationship between `Book` and `CheckoutRecord`. By creating these two one-to-many relationships, we create a many-to-many relationship between `Book` and `Reader` through the `CheckoutRecord` entity. We must do this because EF Core does not support direct many-to-many relationships; instead, it relies on **joining tables** like `CheckoutRecord` in our example. Typically, joining tables only contain foreign keys, but in our example, we also keep track of some other checkout-related data. + + \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/Book.cs b/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/Book.cs new file mode 100644 index 0000000..9f299c3 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/Book.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +public class Book +{ + public int Id { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } + + public List CheckoutRecords { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/LibraryContext.cs b/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/LibraryContext.cs new file mode 100644 index 0000000..7cb1682 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/LibraryContext.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using REPLHelper; + +public class LibraryContext : DbContext +{ + public DbSet Books { get; set; } + public DbSet CheckoutRecords { get; set; } + public DbSet Readers { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite(DBHelper.GetMigrationDbConnectionString()); + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/README.md b/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/README.md new file mode 100644 index 0000000..999aa92 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/README.md @@ -0,0 +1,10 @@ +# Many-to-Many Relationship + +This code example demonstrates how to create a many-to-many relationship in EF Core using a joining table. + +## Code Files: +- [Program.cs](../shared/Program.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [Reader.cs](Reader.cs) +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Book.cs](Book.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/Reader.cs b/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/Reader.cs new file mode 100644 index 0000000..a74da8e --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/Reader.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +public class Reader +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + + public List CheckoutRecords { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/Book.cs b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/Book.cs new file mode 100644 index 0000000..c405bf2 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/Book.cs @@ -0,0 +1,9 @@ +public class Book +{ + public int Id { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } + + public Author Author { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/LibraryContext.cs b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/LibraryContext.cs new file mode 100644 index 0000000..d48a987 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/LibraryContext.cs @@ -0,0 +1,14 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using REPLHelper; + +public class LibraryContext : DbContext +{ + public DbSet Authors { get; set; } + public DbSet Books { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite(DBHelper.GetMigrationDbConnectionString()); + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/README.md b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/README.md new file mode 100644 index 0000000..250f642 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/README.md @@ -0,0 +1,9 @@ +# One-to-Many Relationship + +This code example demonstrates how to create a one-to-many relationship in EF Core using navigation properties. + +## Code Files: +- [Program.cs](../shared/Program.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [Book.cs](Book.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/LibraryContext.cs b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/LibraryContext.cs new file mode 100644 index 0000000..2939bbe --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/LibraryContext.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using REPLHelper; + +public class LibraryContext : DbContext +{ + public DbSet
Addresses { get; set; } + public DbSet Readers { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasOne(r => r.Address) + .WithOne(a => a.Reader) + .HasForeignKey
(a => a.ReaderId); + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite(DBHelper.GetMigrationDbConnectionString()); + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md new file mode 100644 index 0000000..74c4b6a --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md @@ -0,0 +1,9 @@ +# One-to-One Relationship with Manual Foreign Key + +This code example demonstrates how to create a one-to-one relationship in EF Core by manually setting the foreign key using Fluent API. + +## Code Files: +- [Program.cs](../shared/Program.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [Reader.cs](../shared/Reader.cs) +- [Address.cs](../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/LibraryContext.cs b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/LibraryContext.cs new file mode 100644 index 0000000..748d3ca --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/LibraryContext.cs @@ -0,0 +1,14 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using REPLHelper; + +public class LibraryContext : DbContext +{ + public DbSet
Addresses { get; set; } + public DbSet Readers { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlite(DBHelper.GetMigrationDbConnectionString()); + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md new file mode 100644 index 0000000..254cffc --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md @@ -0,0 +1,9 @@ +# One-to-One Relationship + +This code example demonstrates how to create a one-to-one relationship in EF Core using navigation properties. + +## Code Files: +- [Program.cs](../shared/Program.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [Reader.cs](../shared/Reader.cs) +- [Address.cs](../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/shared/Address.cs b/content/efcore/getting-started/samples/defining-entity-relationships/shared/Address.cs new file mode 100644 index 0000000..19147be --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/shared/Address.cs @@ -0,0 +1,9 @@ +public class Address +{ + public int Id { get; set; } + public string City { get; set; } + public string State { get; set; } + + public int ReaderId { get; set; } + public Reader Reader { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/shared/Program.cs b/content/efcore/getting-started/samples/defining-entity-relationships/shared/Program.cs new file mode 100644 index 0000000..2289a79 --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/shared/Program.cs @@ -0,0 +1,14 @@ +using System; +using System.Linq; +using REPLHelper; + +public class Program +{ + public static void Main() + { + using (var context = new LibraryContext()) + { + DBHelper.PrintDatabaseSchema(context); + } + } +} \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/shared/Reader.cs b/content/efcore/getting-started/samples/defining-entity-relationships/shared/Reader.cs new file mode 100644 index 0000000..d8017ab --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/shared/Reader.cs @@ -0,0 +1,8 @@ +public class Reader +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + + public Address Address { get; set; } +} \ No newline at end of file diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index 67fb790..900b5b9 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -3,6 +3,7 @@ - [Understanding Data Models](understanding-data-models.md) - [Generating Databases and Data Models](generating-databases-and-data-models.md) - [Defining Unique Identifiers](defining-unique-identifiers.md) +- [Defining Entity Relationships](defining-entity-relationships.md) - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) - [Manipulating Entities](manipulating-entities.md) From 3e76f2530a36f0522f3f71a6f16b4e7a372ab850 Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Wed, 8 Mar 2017 20:05:08 -0600 Subject: [PATCH 41/56] Resolves #81 - Trap Ryan in Nebraska Ryan is now from a small town in NE, coincidentally named after a breed of cow. --- .../efcore/getting-started/tutorial-database-reference.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/content/efcore/getting-started/tutorial-database-reference.md b/content/efcore/getting-started/tutorial-database-reference.md index d2a1c35..17f8340 100644 --- a/content/efcore/getting-started/tutorial-database-reference.md +++ b/content/efcore/getting-started/tutorial-database-reference.md @@ -58,6 +58,7 @@ Id | City | State ------|------------|--------- 1 | Springview | Nebraska 2 | Thurston | Nebraska -3 | Austin | Texas +3 | Holstein | Nebraska 4 | Gurley | Nebraska -5 | Lincoln | Nebraska \ No newline at end of file +5 | Lincoln | Nebraska +6 | Harrison | Nebraska \ No newline at end of file From 76a07108e7649bde2dcda4dbc86929077932a8ae Mon Sep 17 00:00:00 2001 From: deakgeek Date: Tue, 28 Mar 2017 15:00:55 -0500 Subject: [PATCH 42/56] Resolves #87 - Invalid Database Generation Command --- .../getting-started/generating-databases-and-data-models.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/efcore/getting-started/generating-databases-and-data-models.md b/content/efcore/getting-started/generating-databases-and-data-models.md index f13e91c..c40841e 100644 --- a/content/efcore/getting-started/generating-databases-and-data-models.md +++ b/content/efcore/getting-started/generating-databases-and-data-models.md @@ -18,7 +18,7 @@ dotnet ef migrations add [migration name] Finally, we would run the [dotnet-ef-database-update](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#dotnet-ef-database-update) command to execute the database-creation code. ``` -dotnet ef migrations update +dotnet ef database update ``` After running the above command, we will have a new database that exactly matches our data model. You can run the example below to see what the resulting database schema would look like. It runs the migration commands for you in the cloud so you can test your model in-browser. @@ -45,7 +45,7 @@ If we ever need to make changes to our data model in the future, migrations can ``` dotnet ef migrations add [migration name] -dotnet ef migrations update +dotnet ef database update ``` Anytime we make changes to the data model, we will need to add and run a new migration for the changes to be reflected in our database. From 239ca9679f31cc664ebda57b9afcec02a84210d2 Mon Sep 17 00:00:00 2001 From: deakgeek Date: Wed, 29 Mar 2017 16:10:03 -0500 Subject: [PATCH 43/56] Resolves #85 - Fixes incorrect author ids --- .../tutorial-database-reference.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/content/efcore/getting-started/tutorial-database-reference.md b/content/efcore/getting-started/tutorial-database-reference.md index 17f8340..96b22a9 100644 --- a/content/efcore/getting-started/tutorial-database-reference.md +++ b/content/efcore/getting-started/tutorial-database-reference.md @@ -9,27 +9,27 @@ Id | FirstName | LastName 2 | Mark | Twain 3 | Willa | Cather 4 | Frederick | Douglass -7 | Agatha | Christie -8 | Virginia | Woolf -9 | Frances | Harper -10 | Stephen | Crane +5 | Agatha | Christie +6 | Virginia | Woolf +7 | Frances | Harper +8 | Stephen | Crane ## Books Id | AuthorId | Title | Genre | PublicationYear -----|----------|---------------------------------|------------------|---------------- -1 | 9 | Mrs Dalloway | Literary | 1925 +1 | 6 | Mrs Dalloway | Literary | 1925 2 | 1 | The Scarlet Plague | Science Fiction | 1912 -3 | 8 | The Secret Adversary | Mystery | 1922 -4 | 5 | My Bondage and My Freedom | Narrative | 1855 -5 | 4 | My Antonia | Historical | 1918 -6 | 4 | O Pioneers! | Historical | 1913 +3 | 5 | The Secret Adversary | Mystery | 1922 +4 | 4 | My Bondage and My Freedom | Narrative | 1855 +5 | 3 | My Antonia | Historical | 1918 +6 | 3 | O Pioneers! | Historical | 1913 7 | 2 | Adventures of Huckleberry Finn | Satire | 1884 8 | 2 | The Adventures of Tom Sawyer | Satire | 1876 -9 | 10 | Iola Leroy | Historical | 1892 -10 | 8 | Murder on the Orient Express | Mystery | 1934 +9 | 7 | Iola Leroy | Historical | 1892 +10 | 5 | Murder on the Orient Express | Mystery | 1934 11 | 1 | The Call of the Wild | Adventure | 1903 -12 | 4 | Death Comes for the Archbishop | Historical | 1927 +12 | 3 | Death Comes for the Archbishop | Historical | 1927 ## Checkout Records @@ -61,4 +61,4 @@ Id | City | State 3 | Holstein | Nebraska 4 | Gurley | Nebraska 5 | Lincoln | Nebraska -6 | Harrison | Nebraska \ No newline at end of file +6 | Harrison | Nebraska From 49d195de1fb0ec98fb9a2f3c0d53ba64096c1758 Mon Sep 17 00:00:00 2001 From: Rebecca Dahlman Date: Mon, 3 Apr 2017 17:10:40 -0500 Subject: [PATCH 44/56] Resolves #91 - Makes address dependent on reader --- .../getting-started/samples/shared/Address.cs | 3 ++ .../tutorial-database-reference.md | 32 +++++++++---------- .../tutorial-model-reference.md | 3 ++ 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/content/efcore/getting-started/samples/shared/Address.cs b/content/efcore/getting-started/samples/shared/Address.cs index 8b9a12c..eeed2ef 100644 --- a/content/efcore/getting-started/samples/shared/Address.cs +++ b/content/efcore/getting-started/samples/shared/Address.cs @@ -3,4 +3,7 @@ public class Address public int Id { get; set; } public string City { get; set; } public string State { get; set; } + + public int ReaderId { get; set; } + public Reader Reader { get; set; } } diff --git a/content/efcore/getting-started/tutorial-database-reference.md b/content/efcore/getting-started/tutorial-database-reference.md index 96b22a9..9373409 100644 --- a/content/efcore/getting-started/tutorial-database-reference.md +++ b/content/efcore/getting-started/tutorial-database-reference.md @@ -43,22 +43,22 @@ Id | BookId | ReaderId | CheckoutDate | ReturnDate | DueDate ## Readers -Id | AddressId | FirstName | LastName ------|-----------|------------|------------ -1 | 1 | Andrew | Salami -2 | 2 | Rebecca | Dahlman -3 | 3 | Ryan | Helmoski -4 | 4 | Melia | Deakin -5 | 5 | David | Mikhayelyan -6 | 6 | Aryn | Huck +Id | FirstName | LastName +-----|------------|------------ +1 | Andrew | Salami +2 | Rebecca | Dahlman +3 | Ryan | Helmoski +4 | Melia | Deakin +5 | David | Mikhayelyan +6 | Aryn | Huck ## Addresses -Id | City | State -------|------------|--------- -1 | Springview | Nebraska -2 | Thurston | Nebraska -3 | Holstein | Nebraska -4 | Gurley | Nebraska -5 | Lincoln | Nebraska -6 | Harrison | Nebraska +Id | ReaderId | City | State +------|----------|------------|--------- +1 | 1 | Springview | Nebraska +2 | 2 | Thurston | Nebraska +3 | 3 | Holstein | Nebraska +4 | 4 | Gurley | Nebraska +5 | 5 | Lincoln | Nebraska +6 | 6 | Harrison | Nebraska diff --git a/content/efcore/getting-started/tutorial-model-reference.md b/content/efcore/getting-started/tutorial-model-reference.md index a4ef580..f9687b5 100644 --- a/content/efcore/getting-started/tutorial-model-reference.md +++ b/content/efcore/getting-started/tutorial-model-reference.md @@ -71,5 +71,8 @@ public class Address public int Id { get; set; } public string City { get; set; } public string State { get; set; } + + public int ReaderId { get; set; } + public Reader Reader { get; set; } } ``` \ No newline at end of file From a04f0bd5e8ac3cd29536553d3f9356ac57ebf3f8 Mon Sep 17 00:00:00 2001 From: arynhuck Date: Wed, 5 Apr 2017 18:47:22 -0500 Subject: [PATCH 45/56] Resolves #89 - References in tutorials --- .../efcore/getting-started/manipulating-entities.md | 8 ++++---- content/efcore/getting-started/querying.md | 10 ++++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md index e221ca7..a530ef8 100644 --- a/content/efcore/getting-started/manipulating-entities.md +++ b/content/efcore/getting-started/manipulating-entities.md @@ -1,6 +1,6 @@ # Manipulating Entities -Four operations that we often perform on a record in a database are create, read, update, and delete (commonly referred to as "CRUD" operations). We walked through how to read records from a database in the [Querying Data](querying.md) lesson. In this lesson, we'll learn how to perform the other CRUD operations which allow us to manipulate records in the database. +Four operations that we often perform on a record in a database are Create, Read, Update, and Delete (commonly referred to as "CRUD" operations). We walked through how to read records from a database in the [Querying Data](querying.md) lesson. In this lesson, we'll learn how to perform the other CRUD operations which allow us to manipulate records in the database. > **Note** {.note} > If you want to see the contents of the database or how our entities relate to each other, please refer to the [Database Reference](tutorial-database-reference.md) and [Model Reference](tutorial-model-reference.md) pages. @@ -93,7 +93,7 @@ using (var context = new LibraryContext()) ``` :::repl{data-name=updating-entities} ::: - + Notice we did not have to tell EF Core that the entity had been changed to update its values. This is because the book we retrieved from the database is a **tracked entity**, meaning EF Core will keep track of any changes made to it. EF Core will continue to track changes made to the entity until the context is disposed, which occurs automatically when leaving the `using` block. To learn more about tracked entities, check out the ["Tracking vs. No-Tracking"](https://docs.microsoft.com/en-us/ef/core/querying/tracking) page in the docs. Suppose you want to update an untracked entity. As long as the untracked entity has the same primary key as the record in the database, you can accomplish this using the `DbSet`'s `Update` method. In the following example, we update the book with a primary key of `1`: @@ -132,7 +132,7 @@ using (var context = new LibraryContext()) ## Deleting Related Data -In the previous example, we were able to successfully delete a book, but what happened to that book's checkout records? The short answer is it depends. The way that EF Core handles deletion of an entity with related data depends on several factors including whether the related data is tracked, how EF Core is configured, and how the database is configured. To learn more about the available behaviors and how to configure a certain behavior, check out the [Cascade Delete]() lesson. +In the previous example, we were able to successfully delete a book, but what happened to that book's checkout records? The short answer is it depends. The way that EF Core handles deletion of an entity with related data depends on several factors including whether the related data is tracked, how EF Core is configured, and how the database is configured. To learn more about the available behaviors and how to configure a certain behavior, check out the Configuring Deletion lesson. > **Note** {.note} -> The Cascade Delete lesson has not been added yet. For now, please refer to the [Cascade Delete](https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete) page in the docs. +> The Configuring Deletion lesson has not been added yet. For now, please refer to the [Cascade Delete](https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete) page in the docs. diff --git a/content/efcore/getting-started/querying.md b/content/efcore/getting-started/querying.md index 5f92385..a7073f9 100644 --- a/content/efcore/getting-started/querying.md +++ b/content/efcore/getting-started/querying.md @@ -18,15 +18,13 @@ using (var context = new LibraryContext()) :::repl{data-name=loading-all-entities} ::: -In order to interact with the database via EF Core, we must first create an instance of our context (`LibraryContext`). `LibraryContext` extends EF Core's [`DbContext`](https://msdn.microsoft.com/library/system.data.entity.dbcontext) class which manages entity objects during runtime, and allows us to perform common database operations like running queries. - -Notice that we create the context with the `using` keyword. This automatically disposes the context after the using block has finished executing. Alternatively, we could manually call `LibraryContext.dispose()`, but the `using` method is more convenient and readable. It is imperative that we dispose of the context after we are finished using it because it holds an open connection to the database. +In order to interact with the database via EF Core, we must first create an instance of our context (we learned about contexts in ["Understanding Data Models"](understanding-data-models.md)). Notice that we instantiate the context with the `using` keyword. This automatically disposes the context after the using block has finished executing. Alternatively, we could manually dispose `LibraryContext` with the `dispose` method, but the `using` method is more convenient and readable. It is imperative that we dispose of the context after we are finished using it because it holds an open connection to the database. -Once we have an instance of the context, we can use it to interact with the database. To access the books in the database, we reference the relevant `DbSet` within the context - `Books` in our case - and call the `ToList` method to convert the `DbSet` to a `List`. The resulting list will contain all of the books within the database. +Once we have an instance of the context, we can use it to interact with the database. To access the books in the database, we reference the relevant `DbSet` within the context (`Books` in our case) and call the `ToList` method to convert the `DbSet` to a `List`. The resulting list will contain all of the books within the database. ## Filtering Entities -Loading all of the entities from a database is useful, but there are many use cases where we only want to load a subset of the entities from the database. For example, we may want to filter books by author or genre. EF Core allows us to filter entities via the `Where` extension method. Let's look at an example where we retrieve all Historical books from the database. +Loading all of the entities from a database is useful, but there are many cases where we only want to load a subset of the entities from the database. For example, we may want to filter books by author or genre. EF Core allows us to filter entities via the `Where` extension method. Let's look at an example where we retrieve all Historical books from the database. ```{.snippet} using (var context = new LibraryContext()) @@ -41,7 +39,7 @@ using (var context = new LibraryContext()) We use a lambda expression within the `Where` method to detect if the `Genre` property of each book is equal to "Historical". Books that meet the criteria of the lambda expression will be included in the final result, while books that do not will be excluded. -We could retrieve all of the books like in the previous example and then filter them in our application; however, this would require us to load all of the books into memory, and it does not allow us to take advantage of our database's optimized querying functionality. Allowing the database to do what it does best and perform the filtering for us results in a significant performance increase. Thus, it is important that we filter the `DbSet` with the `Where` method before calling `ToList`. +We could retrieve all of the books like in the previous example and then filter them in our application; however, this would require us to load all of the books into memory, and it does not allow us to take advantage of our database's optimized querying functionality. Allowing the database to perform the filtering for us results in a significant performance increase. Thus, it is important that we filter the `DbSet` with the `Where` method before calling `ToList`. ## Loading a Single Entity From 7e971c9cfc13e9b377880db86dd198236920aeed Mon Sep 17 00:00:00 2001 From: arynhuck Date: Mon, 10 Apr 2017 15:51:23 -0500 Subject: [PATCH 46/56] Resolves #88 and Resolves #25 - Small wording changes and update installing page --- content/efcore/getting-started/README.md | 2 +- .../efcore/getting-started/installing-ef-core.md | 16 +++++++++------- .../efcore/getting-started/intro-to-ef-core.md | 8 ++------ .../getting-started/loading-related-data.md | 2 +- content/efcore/getting-started/querying.md | 2 +- .../getting-started/understanding-data-models.md | 10 +++++----- 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 9514b57..4d724cc 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -2,7 +2,7 @@ ## Who Should Read This -This tutorial is aimed at people who are learning EF Core for the first time. More advanced functionality is covered in the [docs](https://docs.microsoft.com/en-us/ef/). Before beginning this tutorial, you should understand the following topics: +This tutorial is for people who are learning EF Core for the first time. Advanced functionality is covered in the [docs](https://docs.microsoft.com/en-us/ef/). Before beginning this tutorial, you should understand the following topics: - C# (see [Getting Started with C#](https://www.microsoft.com/net/tutorials/csharp/getting-started)) - Relational database concepts diff --git a/content/efcore/getting-started/installing-ef-core.md b/content/efcore/getting-started/installing-ef-core.md index 2e90330..867f10e 100644 --- a/content/efcore/getting-started/installing-ef-core.md +++ b/content/efcore/getting-started/installing-ef-core.md @@ -1,10 +1,10 @@ # Installing EF Core -In this lesson, you will learn how to install EF Core on your machine. You do not need to complete these steps to continue with the rest of the tutorial as the code examples in the other lessons are executable in-browser. +In this lesson, you will learn how to install Entity Framework Core (EF Core) on your machine. ## Install .NET Core -If you haven't already, you will first need to install .NET Core on your machine. Go to the [.NET Core Page](https://www.microsoft.com/net/core) of the Microsoft website, and follow the installation instructions for your platform of choice. You can ensure .NET Core is installed by running the following command: +First, you will need to install .NET Core on your machine. Go to the [.NET Core](https://www.microsoft.com/net/core) page of the Microsoft website, and follow the installation instructions for your platform of choice. You can ensure .NET Core is installed by running the following command: ``` dotnet --version @@ -12,17 +12,19 @@ dotnet --version ## Create New Project -Create a new project by running the following commands (you can skip these steps if you want to add EF Core to an existing project): +Create a new project by running the following commands in command line. You can skip these steps if you want to add EF Core to an existing project: ``` -mkdir MyEfCoreProject # Create directory for project -cd MyEfCoreProject # Navigate to project directory -dotnet new # Initialize .NET Core project (generates Startup.cs and project.json) +mkdir MyEfCoreProject +cd MyEfCoreProject +dotnet new ``` ## Add EF Core to Project -To add EF Core to your project, you need to list it as a dependency in your `project.json` file. You need to add the appropriate package for your database provider as well. See [Database Providers](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs for a full listing of available database providers. In this example, we use Sqlite. +To add EF Core to your project, you need to list it as a dependency in your `project.json` file. You must add the appropriate package for your database provider as well. See [Database Providers](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs for a full listing of available database providers. + +In this example, we use Sqlite: ```{json} "dependencies": { diff --git a/content/efcore/getting-started/intro-to-ef-core.md b/content/efcore/getting-started/intro-to-ef-core.md index 510c446..7d83a57 100644 --- a/content/efcore/getting-started/intro-to-ef-core.md +++ b/content/efcore/getting-started/intro-to-ef-core.md @@ -1,9 +1,5 @@ # Intro to EF Core -Entity Framework Core (EF Core) is a lightweight, extensible, and cross-platform version of Entity Framework. Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects. This allows developers to create and manage databases without most of the data-access code that developers usually need to write.  +Entity Framework Core (EF Core) is a lightweight, extensible, and cross-platform version of Entity Framework. Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects. This allows developers to create and manage databases without most of the data-access code that developers usually need to write. The available databases can be found on the ["Database Providers"](https://docs.microsoft.com/en-us/ef/core/providers/) page in the docs. -EF Core and the latest version of Entity Framework (EF6.x) differ in the features they support. A comparison of the features supported by each can be found on the [feature comparison page](https://docs.microsoft.com/en-us/ef/efcore-and-ef6/features) of the docs. If you want help determining which version is best for your project, check out the ["Which One Is Right for You?"](https://docs.microsoft.com/en-us/ef/efcore-and-ef6/choosing) page. - -## Database Providers - -At the moment, EF Core only supports relational databases, but there are plans to add support for non-relational databases in the future. Supported database providers are listed on the [Database Providers page](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs. +EF Core and the latest version of Entity Framework (EF6.x) differ in the features they support. A comparison of the features supported by each can be found on the ["Feature Comparison" ](https://docs.microsoft.com/en-us/ef/efcore-and-ef6/features) page of the docs. If you want help determining which version is best for your project, check out the ["Which One Is Right for You?"](https://docs.microsoft.com/en-us/ef/efcore-and-ef6/choosing) page. diff --git a/content/efcore/getting-started/loading-related-data.md b/content/efcore/getting-started/loading-related-data.md index fa22c0e..14addb6 100644 --- a/content/efcore/getting-started/loading-related-data.md +++ b/content/efcore/getting-started/loading-related-data.md @@ -48,7 +48,7 @@ using (var context = new LibraryContext()) ## Multi-layer Inclusion -Now, what happens if one of the properties we include also has non-primitive type properties? By default, they won't be loaded from the database, but we can tell EF Core to load them using the `ThenInclude` method. For example, we can determine all of the readers who have checked out a specific book by using `Include` to load the book's checkout records and then using `ThenInclude` to load the reader associated with each checkout record as shown below: +Now, what happens if one of the properties we include also has non-primitive type properties? By default, they won't be loaded from the database, but we can tell EF Core to load them using the `ThenInclude` method. For example, we can determine all of the readers who have checked out a specific book by using `Include` to load the book's checkout records, followed by using `ThenInclude` to load the reader associated with each checkout record as shown below: ```{.snippet} using (var context = new LibraryContext()) diff --git a/content/efcore/getting-started/querying.md b/content/efcore/getting-started/querying.md index a7073f9..2ca26ad 100644 --- a/content/efcore/getting-started/querying.md +++ b/content/efcore/getting-started/querying.md @@ -17,7 +17,7 @@ using (var context = new LibraryContext()) ``` :::repl{data-name=loading-all-entities} ::: - + In order to interact with the database via EF Core, we must first create an instance of our context (we learned about contexts in ["Understanding Data Models"](understanding-data-models.md)). Notice that we instantiate the context with the `using` keyword. This automatically disposes the context after the using block has finished executing. Alternatively, we could manually dispose `LibraryContext` with the `dispose` method, but the `using` method is more convenient and readable. It is imperative that we dispose of the context after we are finished using it because it holds an open connection to the database. Once we have an instance of the context, we can use it to interact with the database. To access the books in the database, we reference the relevant `DbSet` within the context (`Books` in our case) and call the `ToList` method to convert the `DbSet` to a `List`. The resulting list will contain all of the books within the database. diff --git a/content/efcore/getting-started/understanding-data-models.md b/content/efcore/getting-started/understanding-data-models.md index 0cf13c0..f92b69a 100644 --- a/content/efcore/getting-started/understanding-data-models.md +++ b/content/efcore/getting-started/understanding-data-models.md @@ -8,9 +8,9 @@ A data model is a representation of the different types of information within a ## Defining a Data Model -In EF Core, a data model is defined using "plain-old" C# object (POCO) classes. These are classes that solely consist of getters and setters. In EF Core, these POCO classes are referred to as **entities** or **entity classes**. +In EF Core, a data model is defined using "Plain-Old" C# Object (POCO) classes. These are classes that solely consist of getters and setters. In EF Core, these POCO classes are referred to as **entities** or **entity classes**. -Let's look at an example. Imagine we are creating a library application. What types of information would be in such a system? Books and readers are two good examples. To include these types of information in our data model, we first define an entity for each of them like so: +Let's look at an example. Imagine we are creating a library application. What types of information would be in such a system? Books and people who read the books (we'll call them "readers") are two good examples. To include these types of information in our data model, we first define an entity for each of them like so: ```{C#} public class Book @@ -29,7 +29,7 @@ public class Reader ``` > **Note** {.note} -> We will be using this library example throughout the tutorial. It is very simple at the moment, but we will be adding more data members and entities in later lessons to make it more like a full-fledged library application. +> We will use this library example throughout the tutorial and will add more data members and entities in later lessons. After defining our entities, we next need to register them with EF Core. We do this by first extending the abstract class [DbContext](https://msdn.microsoft.com/library/system.data.entity.dbcontext), which serves as the connection between our C# code and database. Then we add our entities as `DbSet` properties to the context as shown below: @@ -43,6 +43,6 @@ public class LibraryContext : DbContext Now that we have defined our data model, we can use EF Core to interact with a matching database. It is important that the data model and database schema match because otherwise EF Core won't be able to translate between the two, and it will just throw an error instead. -When mapping the data model to the database, EF Core makes some assumptions which allow it to perform the mapping automatically. For example, it expects each entity in the data model to correspond to a database table that shares the same name as the `DbSet<>` property in the `DbContext`. In our library example, a matching database would have a "Books" table and a "Readers" table. Likewise, it expects each property of an entity to correspond to a table column that shares the same name and datatype. Thus, the "Books" table in our example would have an "Id" column with a `INT` datatype, a "Title" column with a `VARCHAR` datatype, and a "PublicationYear" column with an `INT` datatype. These assumptions made by EF Core are referred to as **conventions**, and they are simply its default behavior. +When mapping the data model to the database, EF Core makes some assumptions that allow it to perform the mapping automatically. For example, it expects each entity in the data model to correspond to a database table that shares the same name as the `DbSet<>` property in the `DbContext`. In our library example, a matching database would have a "Books" table and a "Readers" table. Likewise, it expects each property of an entity to correspond to a table column that shares the same name and data type. Thus, the "Books" table in our example would have an "Id" column with a `INT` data type, a "Title" column with a `VARCHAR` data type, and a "PublicationYear" column with an `INT` data type. These assumptions made by EF Core are referred to as **conventions**, and they are simply its default behavior. -In cases where you don't want the default behavior, conventions can be overridden through two different methods. **Data Annotations** involves annotating your entity classes to specify desired behavior. **Fluent API** is a programmatic method of configuring EF Core, and it overrides data annotations. This tutorial focuses on Fluent API because it supports some features that are not available with data annotations. We will learn more about using Fluent API to configure EF Core in upcoming lessons. \ No newline at end of file +In cases where you don't want the default behavior, conventions can be overridden through two different methods. **Data Annotations** involves annotating your entity classes to specify desired behavior. **Fluent API** is a programmatic method of configuring EF Core, and it overrides data annotations. This tutorial focuses on Fluent API because it supports some features that are not available with data annotations. We will learn more about using Fluent API to configure EF Core in upcoming lessons. From 0cb7c933cd3f1c0caa36a2b55b47125acb0074da Mon Sep 17 00:00:00 2001 From: deakgeek Date: Mon, 10 Apr 2017 17:30:09 -0500 Subject: [PATCH 47/56] Resolves #96 - Updates installing tutorial to use csproj --- content/efcore/getting-started/README.md | 2 +- .../generating-databases-and-data-models.md | 4 +- .../getting-started/installing-ef-core.md | 131 ++++++++++-------- content/efcore/getting-started/toc.md | 2 +- 4 files changed, 80 insertions(+), 59 deletions(-) diff --git a/content/efcore/getting-started/README.md b/content/efcore/getting-started/README.md index 4d724cc..e79d907 100644 --- a/content/efcore/getting-started/README.md +++ b/content/efcore/getting-started/README.md @@ -14,7 +14,6 @@ This tutorial is for people who are learning EF Core for the first time. Advance This tutorial will cover the following topics: - [Intro to EF Core](intro-to-ef-core.md) -- [Installing EF Core](installing-ef-core.md) - [Understanding Data Models](understanding-data-models.md) - [Generating Databases and Data Models](generating-databases-and-data-models.md) - [Defining Unique Identifiers](defining-unique-identifiers.md) @@ -22,5 +21,6 @@ This tutorial will cover the following topics: - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) - [Manipulating Entities](manipulating-entities.md) +- [Appendix: Installing EF Core](installing-ef-core.md) - [Appendix: Data Model Reference](tutorial-model-reference.md) - [Appendix: Database Reference](tutorial-database-reference.md) diff --git a/content/efcore/getting-started/generating-databases-and-data-models.md b/content/efcore/getting-started/generating-databases-and-data-models.md index c40841e..1b79b65 100644 --- a/content/efcore/getting-started/generating-databases-and-data-models.md +++ b/content/efcore/getting-started/generating-databases-and-data-models.md @@ -13,7 +13,7 @@ dotnet ef migrations add [migration name] ``` > **Note** {.note} -> If the above command fails with the error message, `No executable found matching command "dotnet-ef"`, make sure `Microsoft.EntityFrameworkCore.Tools` has been installed for your project, as shown in the [Installing EF Core](installing-ef-core.md) lesson. Also ensure you are running the command from the directory that contains your `project.json` file. +> If the above command fails with the error message, `No executable found matching command "dotnet-ef"`, make sure `Microsoft.EntityFrameworkCore.Tools` has been installed for your project, as shown in the [Installing EF Core](installing-ef-core.md) appendix. Also ensure you are running the command from the directory that contains your `project.json` file. Finally, we would run the [dotnet-ef-database-update](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#dotnet-ef-database-update) command to execute the database-creation code. @@ -52,7 +52,7 @@ Anytime we make changes to the data model, we will need to add and run a new mig ## Generating a Data Model from an Existing Database -We can also have EF Core automatically generate a data model from an existing database. First, we create an EF Core project by following the steps in the [Installing EF Core](installing-ef-core.md) lesson. Once the project is ready-to-go, we navigate to the directory that contains the `project.json` file in command line. Next, we run the [dotnet-ef-dbcontext-scaffold](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#dotnet-ef-dbcontext-scaffold) command to create a model from the existing database. +We can also have EF Core automatically generate a data model from an existing database. First, we create an EF Core project by following the steps in the [Installing EF Core](installing-ef-core.md) appendix. Once the project is ready-to-go, we navigate to the directory that contains the `project.json` file in command line. Next, we run the [dotnet-ef-dbcontext-scaffold](https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet#dotnet-ef-dbcontext-scaffold) command to create a model from the existing database. ``` dotnet ef dbcontext scaffold diff --git a/content/efcore/getting-started/installing-ef-core.md b/content/efcore/getting-started/installing-ef-core.md index 867f10e..8b4dc34 100644 --- a/content/efcore/getting-started/installing-ef-core.md +++ b/content/efcore/getting-started/installing-ef-core.md @@ -1,58 +1,79 @@ -# Installing EF Core - +# Installing EF Core + In this lesson, you will learn how to install Entity Framework Core (EF Core) on your machine. - -## Install .NET Core - -First, you will need to install .NET Core on your machine. Go to the [.NET Core](https://www.microsoft.com/net/core) page of the Microsoft website, and follow the installation instructions for your platform of choice. You can ensure .NET Core is installed by running the following command: - -``` -dotnet --version -``` - -## Create New Project - -Create a new project by running the following commands in command line. You can skip these steps if you want to add EF Core to an existing project: - -``` + +## Install .NET Core + +First, you will need to install .NET Core on your machine. Go to the [.NET Core](https://www.microsoft.com/net/core) page of the Microsoft website, and follow the installation instructions for your platform of choice. You can ensure .NET Core is installed by running the following command: + +``` +dotnet --version +``` + +## Create New Project + +Create a new project by running the following commands in command line. You can skip these steps if you want to add EF Core to an existing project: + +``` mkdir MyEfCoreProject cd MyEfCoreProject -dotnet new -``` - -## Add EF Core to Project - -To add EF Core to your project, you need to list it as a dependency in your `project.json` file. You must add the appropriate package for your database provider as well. See [Database Providers](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs for a full listing of available database providers. - -In this example, we use Sqlite: - -```{json} -"dependencies": { - "Microsoft.EntityFrameworkCore.Sqlite": "1.0.0", - "Microsoft.EntityFrameworkCore.Design": { - "version": "1.0.0-preview2-final", - "type": "build" - } -} -``` - -To add EF Core functionality to the [.NET Core Command-Line Interface](https://docs.microsoft.com/en-us/dotnet/articles/core/tools/), you need to add a package to the `tools` section of `project.json`: - -``` -"tools": { - "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final" -} -``` - -Once you have updated `package.json`, run the following command to install your project's tools and dependencies: - -``` -dotnet restore -``` - -After running this command, EF Core should be installed on your machine. You can run the following command to ensure EF Core was installed correctly: - -``` -dotnet ef --help -``` - +dotnet new console +``` + +## Add EF Core to Project + +To add EF Core to your project, you need to list it as a dependency in your `csproj` file: + +```{xml} + +``` + +You also must add the appropriate package for your database provider as a dependency. See [Database Providers](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs for a full listing of available database providers. In this example, we use SQLite: + +```{xml} + +``` + +To add EF Core functionality to the [.NET Core Command-Line Interface](https://docs.microsoft.com/en-us/dotnet/articles/core/tools/), you need to add the EF Core tools package to the tools section of your `csproj`. + +```{xml} + +``` + +After adding these packages, your `csproj` should look similar to this example: + +```{xml} + + + Exe + netcoreapp1.1 + + + + + + + + + + +``` + +Once you have updated the `csproj` file, run the following command in the project directory to install your project's tools and dependencies: + +``` +dotnet restore +``` + +After running this command, EF Core should be installed on your machine. You can run the following command to ensure it installed correctly: + +``` +dotnet ef --help +``` \ No newline at end of file diff --git a/content/efcore/getting-started/toc.md b/content/efcore/getting-started/toc.md index 900b5b9..812c293 100644 --- a/content/efcore/getting-started/toc.md +++ b/content/efcore/getting-started/toc.md @@ -1,5 +1,4 @@ - [Intro to EF Core](intro-to-ef-core.md) -- [Installing EF Core](installing-ef-core.md) - [Understanding Data Models](understanding-data-models.md) - [Generating Databases and Data Models](generating-databases-and-data-models.md) - [Defining Unique Identifiers](defining-unique-identifiers.md) @@ -7,5 +6,6 @@ - [Querying Data](querying.md) - [Loading Related Data](loading-related-data.md) - [Manipulating Entities](manipulating-entities.md) +- [Appendix: Installing EF Core](installing-ef-core.md) - [Appendix: Data Model Reference](tutorial-model-reference.md) - [Appendix: Database Reference](tutorial-database-reference.md) From 59c8e3d48ac2e39c63b25d272e75351d7fbdb7ba Mon Sep 17 00:00:00 2001 From: arynhuck Date: Mon, 10 Apr 2017 18:30:57 -0500 Subject: [PATCH 48/56] Transferring a change On merging the new Installing EF Core lesson, one small change got overridden from the small wording issue. This has been fixed (a new line was needed to separate a statement). --- content/efcore/getting-started/installing-ef-core.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/content/efcore/getting-started/installing-ef-core.md b/content/efcore/getting-started/installing-ef-core.md index 8b4dc34..9d3dec9 100644 --- a/content/efcore/getting-started/installing-ef-core.md +++ b/content/efcore/getting-started/installing-ef-core.md @@ -29,7 +29,9 @@ To add EF Core to your project, you need to list it as a dependency in your `csp Version="1.0.0" /> ``` -You also must add the appropriate package for your database provider as a dependency. See [Database Providers](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs for a full listing of available database providers. In this example, we use SQLite: +You also must add the appropriate package for your database provider as a dependency. See [Database Providers](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs for a full listing of available database providers. + +In this example, we use SQLite: ```{xml} @@ -76,4 +78,4 @@ After running this command, EF Core should be installed on your machine. You can ``` dotnet ef --help -``` \ No newline at end of file +``` From bccaaeb49cc74d5d34857afaff820c61f1f8c689 Mon Sep 17 00:00:00 2001 From: deakgeek Date: Tue, 11 Apr 2017 14:44:23 -0500 Subject: [PATCH 49/56] Updated Installing EF Core tutorial with correct dependencies (#102) --- content/efcore/getting-started/installing-ef-core.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/efcore/getting-started/installing-ef-core.md b/content/efcore/getting-started/installing-ef-core.md index 9d3dec9..06beca2 100644 --- a/content/efcore/getting-started/installing-ef-core.md +++ b/content/efcore/getting-started/installing-ef-core.md @@ -25,8 +25,8 @@ dotnet new console To add EF Core to your project, you need to list it as a dependency in your `csproj` file: ```{xml} - + ``` You also must add the appropriate package for your database provider as a dependency. See [Database Providers](https://docs.microsoft.com/en-us/ef/core/providers/) in the docs for a full listing of available database providers. @@ -34,7 +34,8 @@ You also must add the appropriate package for your database provider as a depend In this example, we use SQLite: ```{xml} - + ``` To add EF Core functionality to the [.NET Core Command-Line Interface](https://docs.microsoft.com/en-us/dotnet/articles/core/tools/), you need to add the EF Core tools package to the tools section of your `csproj`. @@ -58,7 +59,6 @@ After adding these packages, your `csproj` should look similar to this example: Version="1.0.0" /> - Date: Fri, 14 Apr 2017 22:01:21 -0500 Subject: [PATCH 50/56] Resolves #98 - Updates manipulating entities lesson with information on deletion behavior --- content/efcore/getting-started/manipulating-entities.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md index a530ef8..4385436 100644 --- a/content/efcore/getting-started/manipulating-entities.md +++ b/content/efcore/getting-started/manipulating-entities.md @@ -132,7 +132,4 @@ using (var context = new LibraryContext()) ## Deleting Related Data -In the previous example, we were able to successfully delete a book, but what happened to that book's checkout records? The short answer is it depends. The way that EF Core handles deletion of an entity with related data depends on several factors including whether the related data is tracked, how EF Core is configured, and how the database is configured. To learn more about the available behaviors and how to configure a certain behavior, check out the Configuring Deletion lesson. - -> **Note** {.note} -> The Configuring Deletion lesson has not been added yet. For now, please refer to the [Cascade Delete](https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete) page in the docs. +In the previous example, we were able to successfully delete a book, but what happened to that book's checkout records? The short answer is it depends. The way that EF Core handles deletion of an entity with related data depends on several factors including whether the related data is tracked, how EF Core is configured, and how the database is configured. By default, EF Core will delete any tracked dependents of the principal entity when it is deleted. This is known as **cascade deletion** because the deletion is cascaded down to the dependents. There are other deletion behaviors, but they are too advanced for this tutorial. For more information on these behaviors, see the ["Cascade Delete"](https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete) page in the docs. \ No newline at end of file From 903a7d65f3e09840426fb7894fed6d020b5ff0e0 Mon Sep 17 00:00:00 2001 From: arynhuck Date: Fri, 14 Apr 2017 22:03:58 -0500 Subject: [PATCH 51/56] Resolves #105 - Good-bye "quotations" Removes quotations from hyperlinks. --- content/efcore/getting-started/intro-to-ef-core.md | 4 ++-- content/efcore/getting-started/manipulating-entities.md | 2 +- content/efcore/getting-started/querying.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/efcore/getting-started/intro-to-ef-core.md b/content/efcore/getting-started/intro-to-ef-core.md index 7d83a57..4e820e3 100644 --- a/content/efcore/getting-started/intro-to-ef-core.md +++ b/content/efcore/getting-started/intro-to-ef-core.md @@ -1,5 +1,5 @@ # Intro to EF Core -Entity Framework Core (EF Core) is a lightweight, extensible, and cross-platform version of Entity Framework. Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects. This allows developers to create and manage databases without most of the data-access code that developers usually need to write. The available databases can be found on the ["Database Providers"](https://docs.microsoft.com/en-us/ef/core/providers/) page in the docs. +Entity Framework Core (EF Core) is a lightweight, extensible, and cross-platform version of Entity Framework. Entity Framework is an object-relational mapper (O/RM) that enables .NET developers to work with a database using .NET objects. This allows developers to create and manage databases without most of the data-access code that developers usually need to write. The available databases can be found on the [Database Providers](https://docs.microsoft.com/en-us/ef/core/providers/) page in the docs. -EF Core and the latest version of Entity Framework (EF6.x) differ in the features they support. A comparison of the features supported by each can be found on the ["Feature Comparison" ](https://docs.microsoft.com/en-us/ef/efcore-and-ef6/features) page of the docs. If you want help determining which version is best for your project, check out the ["Which One Is Right for You?"](https://docs.microsoft.com/en-us/ef/efcore-and-ef6/choosing) page. +EF Core and the latest version of Entity Framework (EF6.x) differ in the features they support. A comparison of the features supported by each can be found on the [Feature Comparison ](https://docs.microsoft.com/en-us/ef/efcore-and-ef6/features) page of the docs. If you want help determining which version is best for your project, check out the [Which One Is Right for You?](https://docs.microsoft.com/en-us/ef/efcore-and-ef6/choosing) page. diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md index 4385436..f8b0e3e 100644 --- a/content/efcore/getting-started/manipulating-entities.md +++ b/content/efcore/getting-started/manipulating-entities.md @@ -94,7 +94,7 @@ using (var context = new LibraryContext()) :::repl{data-name=updating-entities} ::: -Notice we did not have to tell EF Core that the entity had been changed to update its values. This is because the book we retrieved from the database is a **tracked entity**, meaning EF Core will keep track of any changes made to it. EF Core will continue to track changes made to the entity until the context is disposed, which occurs automatically when leaving the `using` block. To learn more about tracked entities, check out the ["Tracking vs. No-Tracking"](https://docs.microsoft.com/en-us/ef/core/querying/tracking) page in the docs. +Notice we did not have to tell EF Core that the entity had been changed to update its values. This is because the book we retrieved from the database is a **tracked entity**, meaning EF Core will keep track of any changes made to it. EF Core will continue to track changes made to the entity until the context is disposed, which occurs automatically when leaving the `using` block. To learn more about tracked entities, check out the [Tracking vs. No-Tracking](https://docs.microsoft.com/en-us/ef/core/querying/tracking) page in the docs. Suppose you want to update an untracked entity. As long as the untracked entity has the same primary key as the record in the database, you can accomplish this using the `DbSet`'s `Update` method. In the following example, we update the book with a primary key of `1`: diff --git a/content/efcore/getting-started/querying.md b/content/efcore/getting-started/querying.md index 2ca26ad..d1f1f0d 100644 --- a/content/efcore/getting-started/querying.md +++ b/content/efcore/getting-started/querying.md @@ -18,7 +18,7 @@ using (var context = new LibraryContext()) :::repl{data-name=loading-all-entities} ::: -In order to interact with the database via EF Core, we must first create an instance of our context (we learned about contexts in ["Understanding Data Models"](understanding-data-models.md)). Notice that we instantiate the context with the `using` keyword. This automatically disposes the context after the using block has finished executing. Alternatively, we could manually dispose `LibraryContext` with the `dispose` method, but the `using` method is more convenient and readable. It is imperative that we dispose of the context after we are finished using it because it holds an open connection to the database. +In order to interact with the database via EF Core, we must first create an instance of our context (we learned about contexts in [Understanding Data Models](understanding-data-models.md)). Notice that we instantiate the context with the `using` keyword. This automatically disposes the context after the using block has finished executing. Alternatively, we could manually dispose `LibraryContext` with the `dispose` method, but the `using` method is more convenient and readable. It is imperative that we dispose of the context after we are finished using it because it holds an open connection to the database. Once we have an instance of the context, we can use it to interact with the database. To access the books in the database, we reference the relevant `DbSet` within the context (`Books` in our case) and call the `ToList` method to convert the `DbSet` to a `List`. The resulting list will contain all of the books within the database. From 0fac0ead0485804ab21c0f8a67a69d139986dcfb Mon Sep 17 00:00:00 2001 From: deakgeek Date: Sat, 15 Apr 2017 15:26:58 -0500 Subject: [PATCH 52/56] Resolves #104 - Shows relevant files first in code examples --- .../defining-entity-relationships.md | 16 ++++++++-------- .../many-to-many-relationship/README.md | 6 +++--- .../one-to-many-relationship/README.md | 6 +++--- .../one-to-one-manual-foreign-key/README.md | 4 ++-- .../one-to-one-relationship/README.md | 6 +++--- .../composite-key/README.md | 4 ++-- .../primary-key/README.md | 4 ++-- .../unconventional-key-name/README.md | 4 ++-- .../generate-database/README.md | 6 +++--- .../loading-related-data/count-method/README.md | 4 ++-- .../field-not-included/README.md | 2 +- .../README.md | 4 ++-- .../include-method/README.md | 4 ++-- .../loading-related-data/load-method/README.md | 2 +- .../loading-related-data/max-method/README.md | 4 ++-- .../multiple-include-methods/README.md | 4 ++-- .../loading-related-data/query-method/README.md | 2 +- .../then-include-method-chain/README.md | 4 ++-- .../then-include-method/README.md | 4 ++-- .../add-new-entity-to-existing/README.md | 4 ++-- .../adding-entities/README.md | 4 ++-- .../adding-related-entities/README.md | 4 ++-- .../deleting-entities/README.md | 2 +- .../updating-entities/README.md | 2 +- .../updating-untracked-entities/README.md | 2 +- .../querying/filtering-entities/README.md | 2 +- .../querying/loading-all-entities/README.md | 2 +- .../querying/loading-single-entity/README.md | 2 +- 28 files changed, 57 insertions(+), 57 deletions(-) diff --git a/content/efcore/getting-started/defining-entity-relationships.md b/content/efcore/getting-started/defining-entity-relationships.md index 538cba9..e1fe32e 100644 --- a/content/efcore/getting-started/defining-entity-relationships.md +++ b/content/efcore/getting-started/defining-entity-relationships.md @@ -101,21 +101,21 @@ This time we added a navigation property with an `Author` data type to `Book` an In this example, we define a many-to-many relationship between `Reader` and `Book`. ```{.snippet} -public class Reader +public class Book { public int Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } + public string Title { get; set; } + public string Genre { get; set; } + public int PublicationYear { get; set; } public List CheckoutRecords { get; set; } } - -public class Book + +public class Reader { public int Id { get; set; } - public string Title { get; set; } - public string Genre { get; set; } - public int PublicationYear { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } public List CheckoutRecords { get; set; } } diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/README.md b/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/README.md index 999aa92..c14765d 100644 --- a/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/README.md +++ b/content/efcore/getting-started/samples/defining-entity-relationships/many-to-many-relationship/README.md @@ -3,8 +3,8 @@ This code example demonstrates how to create a many-to-many relationship in EF Core using a joining table. ## Code Files: -- [Program.cs](../shared/Program.cs) -- [LibraryContext.cs](LibraryContext.cs) +- [Book.cs](Book.cs) - [Reader.cs](Reader.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) -- [Book.cs](Book.cs) \ No newline at end of file +- [LibraryContext.cs](LibraryContext.cs) +- [Program.cs](../shared/Program.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/README.md b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/README.md index 250f642..5714555 100644 --- a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/README.md +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-many-relationship/README.md @@ -3,7 +3,7 @@ This code example demonstrates how to create a one-to-many relationship in EF Core using navigation properties. ## Code Files: -- [Program.cs](../shared/Program.cs) -- [LibraryContext.cs](LibraryContext.cs) - [Author.cs](../../shared/Author.cs) -- [Book.cs](Book.cs) \ No newline at end of file +- [Book.cs](Book.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [Program.cs](../shared/Program.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md index 74c4b6a..1fbeb50 100644 --- a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md @@ -3,7 +3,7 @@ This code example demonstrates how to create a one-to-one relationship in EF Core by manually setting the foreign key using Fluent API. ## Code Files: -- [Program.cs](../shared/Program.cs) - [LibraryContext.cs](LibraryContext.cs) +- [Address.cs](../shared/Address.cs) - [Reader.cs](../shared/Reader.cs) -- [Address.cs](../shared/Address.cs) \ No newline at end of file +- [Program.cs](../shared/Program.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md index 254cffc..d69cb34 100644 --- a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md @@ -3,7 +3,7 @@ This code example demonstrates how to create a one-to-one relationship in EF Core using navigation properties. ## Code Files: -- [Program.cs](../shared/Program.cs) -- [LibraryContext.cs](LibraryContext.cs) - [Reader.cs](../shared/Reader.cs) -- [Address.cs](../shared/Address.cs) \ No newline at end of file +- [Address.cs](../shared/Address.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [Program.cs](../shared/Program.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/README.md b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/README.md index 11fddf2..29b5510 100644 --- a/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/README.md +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/composite-key/README.md @@ -3,8 +3,8 @@ This code example demonstrates how to configure a composite key in EF Core via Fluent API. ## Code Files: -- [Program.cs](Program.cs) - [LibraryContext.cs](LibraryContext.cs) - [CheckoutRecord.cs](CheckoutRecord.cs) - [Book.cs](Book.cs) -- [Reader.cs](Reader.cs) \ No newline at end of file +- [Reader.cs](Reader.cs) +- [Program.cs](Program.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/README.md b/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/README.md index 026ee02..1ce6232 100644 --- a/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/README.md +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/primary-key/README.md @@ -3,6 +3,6 @@ This code example demonstrates how primary keys work in EF Core by convention. ## Code Files: -- [Program.cs](Program.cs) +- [Book.cs](Book.cs) - [LibraryContext.cs](LibraryContext.cs) -- [Book.cs](Book.cs) \ No newline at end of file +- [Program.cs](Program.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/README.md b/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/README.md index 87fce9e..526035a 100644 --- a/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/README.md +++ b/content/efcore/getting-started/samples/defining-unique-identifiers/unconventional-key-name/README.md @@ -3,6 +3,6 @@ This code example demonstrates how to set an unconventionally-named property as the primary key in EF Core via Fluent API. ## Code Files: -- [Program.cs](Program.cs) - [LibraryContext.cs](LibraryContext.cs) -- [Book.cs](Book.cs) \ No newline at end of file +- [Book.cs](Book.cs) +- [Program.cs](Program.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/README.md b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/README.md index 222a6c9..e4c60f5 100644 --- a/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/README.md +++ b/content/efcore/getting-started/samples/generating-databases-and-data-models/generate-database/README.md @@ -3,7 +3,7 @@ This code example demonstrates how to generate a database from a data model and print its resulting schema through `REPLService`. ## Code Files: -- [Program.cs](Program.cs) -- [LibraryContext.cs](LibraryContext.cs) - [Book.cs](Book.cs) -- [Reader.cs](Reader.cs) \ No newline at end of file +- [Reader.cs](Reader.cs) +- [LibraryContext.cs](LibraryContext.cs) +- [Program.cs](Program.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/count-method/README.md b/content/efcore/getting-started/samples/loading-related-data/count-method/README.md index 6023b40..666d261 100644 --- a/content/efcore/getting-started/samples/loading-related-data/count-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/count-method/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to query related data from the ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../../shared/LibraryContext.cs) -- [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md b/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md index 978220e..9817196 100644 --- a/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/field-not-included/README.md @@ -4,9 +4,9 @@ This code example demonstrates how EF Core loads entities from a database and th ## Code Files: - [Program.cs](Program.cs) +- [Book.cs](../../shared/Book.cs) - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) -- [Book.cs](../../shared/Book.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md index 9beffc6..a2a0364 100644 --- a/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to load multiple levels and la ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) -- [Author.cs](../../shared/Author.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) +- [Author.cs](../../shared/Author.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/include-method/README.md b/content/efcore/getting-started/samples/loading-related-data/include-method/README.md index 3c9a0a2..c5ac414 100644 --- a/content/efcore/getting-started/samples/loading-related-data/include-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/include-method/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to load related data from the ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../../shared/LibraryContext.cs) -- [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) +- [Author.cs](../../shared/Author.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/load-method/README.md b/content/efcore/getting-started/samples/loading-related-data/load-method/README.md index e4fbe4c..019b1bc 100644 --- a/content/efcore/getting-started/samples/loading-related-data/load-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/load-method/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to load related data from the ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/max-method/README.md b/content/efcore/getting-started/samples/loading-related-data/max-method/README.md index 6aa2a3e..57319b0 100644 --- a/content/efcore/getting-started/samples/loading-related-data/max-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/max-method/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to query related data from the ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../../shared/LibraryContext.cs) -- [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md index 159da96..ae8d717 100644 --- a/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to load related data from the ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../../shared/LibraryContext.cs) -- [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Author.cs](../../shared/Author.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/query-method/README.md b/content/efcore/getting-started/samples/loading-related-data/query-method/README.md index 475a744..13e1f1f 100644 --- a/content/efcore/getting-started/samples/loading-related-data/query-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/query-method/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to load and query related data ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [Book.cs](../../shared/Book.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md index 6e47b07..b59048c 100644 --- a/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to load multiple levels and la ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../../shared/LibraryContext.cs) -- [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md b/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md index f57a0d0..7f9cf77 100644 --- a/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to load multiple levels of rel ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) -- [Author.cs](../../shared/Author.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md index 4f90668..42ffbd8 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to add a new entity to an exis ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../shared/LibraryContext.cs) -- [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md index 4a55735..32d92f8 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to add entities to a database. ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../shared/LibraryContext.cs) -- [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md index 069906d..0d8ebb6 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to add related entities to a d ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../shared/LibraryContext.cs) -- [Book.cs](../../shared/Book.cs) - [Author.cs](../../shared/Author.cs) +- [Book.cs](../../shared/Book.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md index 15d49a7..8ef0684 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/deleting-entities/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to delete entities from a data ## Code Files: - [Program.cs](Program.cs) +- [Author.cs](../../shared/Author.cs) - [LibraryContext.cs](../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) -- [Author.cs](../../shared/Author.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md index b90c043..f5d550c 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/README.md @@ -4,8 +4,8 @@ This code example demonstrates how to use EF Core to update entities to a databa ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md index 1e52b18..ac194ec 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/README.md @@ -4,8 +4,8 @@ This code example demonstrates how to use EF Core to update untracked entities i ## Code Files: - [Program.cs](Program.cs) -- [LibraryContext.cs](../shared/LibraryContext.cs) - [Book.cs](../../shared/Book.cs) +- [LibraryContext.cs](../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) diff --git a/content/efcore/getting-started/samples/querying/filtering-entities/README.md b/content/efcore/getting-started/samples/querying/filtering-entities/README.md index 4e91fd0..cb356d4 100644 --- a/content/efcore/getting-started/samples/querying/filtering-entities/README.md +++ b/content/efcore/getting-started/samples/querying/filtering-entities/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to query a subset of entities ## Code Files: - [Program.cs](Program.cs) +- [Book.cs](../../shared/Book.cs) - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) -- [Book.cs](../../shared/Book.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/querying/loading-all-entities/README.md b/content/efcore/getting-started/samples/querying/loading-all-entities/README.md index e16c85e..6cbd1f3 100644 --- a/content/efcore/getting-started/samples/querying/loading-all-entities/README.md +++ b/content/efcore/getting-started/samples/querying/loading-all-entities/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to query all entities from the ## Code Files: - [Program.cs](Program.cs) +- [Book.cs](../../shared/Book.cs) - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) -- [Book.cs](../../shared/Book.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/querying/loading-single-entity/README.md b/content/efcore/getting-started/samples/querying/loading-single-entity/README.md index 131a4af..42a6758 100644 --- a/content/efcore/getting-started/samples/querying/loading-single-entity/README.md +++ b/content/efcore/getting-started/samples/querying/loading-single-entity/README.md @@ -4,9 +4,9 @@ This code example demonstrates how to use EF Core to query a single entity from ## Code Files: - [Program.cs](Program.cs) +- [Book.cs](../../shared/Book.cs) - [LibraryContext.cs](../../shared/LibraryContext.cs) - [Author.cs](../../shared/Author.cs) -- [Book.cs](../../shared/Book.cs) - [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) - [Reader.cs](../../shared/Reader.cs) - [Address.cs](../../shared/Address.cs) \ No newline at end of file From c9f4b11b0841325e844790b9edc59723e0a940a9 Mon Sep 17 00:00:00 2001 From: deakgeek Date: Mon, 17 Apr 2017 15:58:32 -0500 Subject: [PATCH 53/56] Resolves #108 - Adds AddressId to Reader in 2nd defining relationships example --- .../one-to-one-manual-foreign-key/LibraryContext.cs | 2 +- .../samples/defining-entity-relationships/shared/Reader.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/LibraryContext.cs b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/LibraryContext.cs index 2939bbe..5e9366a 100644 --- a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/LibraryContext.cs +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/LibraryContext.cs @@ -12,7 +12,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity() .HasOne(r => r.Address) .WithOne(a => a.Reader) - .HasForeignKey
(a => a.ReaderId); + .HasForeignKey
(a => a.ReaderId); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/shared/Reader.cs b/content/efcore/getting-started/samples/defining-entity-relationships/shared/Reader.cs index d8017ab..f5cb307 100644 --- a/content/efcore/getting-started/samples/defining-entity-relationships/shared/Reader.cs +++ b/content/efcore/getting-started/samples/defining-entity-relationships/shared/Reader.cs @@ -4,5 +4,6 @@ public class Reader public string FirstName { get; set; } public string LastName { get; set; } + public int AddressId { get; set; } public Address Address { get; set; } } \ No newline at end of file From c17a5d242b6e8ba6a08ef0bdc9be24b2e3bade7f Mon Sep 17 00:00:00 2001 From: arynhuck Date: Mon, 24 Apr 2017 16:33:46 -0500 Subject: [PATCH 54/56] Resolves #100 - Better Outputs --- .../getting-started/manipulating-entities.md | 23 +++++++++------- .../count-method/Program.cs | 2 +- .../Program.cs | 5 ++-- .../include-method/Program.cs | 6 +++-- .../load-method/Program.cs | 16 ++++++----- .../max-method/Program.cs | 2 +- .../multiple-include-methods/Program.cs | 7 ++++- .../query-method/Program.cs | 4 +++ .../then-include-method-chain/Program.cs | 4 ++- .../then-include-method/Program.cs | 8 ++++-- .../add-new-entity-to-existing/Program.cs | 4 ++- .../adding-entities/Program.cs | 2 +- .../adding-related-entities/Program.cs | 7 +++-- .../updating-entities/Program.cs | 27 +++++++++++-------- .../updating-untracked-entities/Program.cs | 20 ++++++++------ .../querying/filtering-entities/Program.cs | 3 ++- .../querying/loading-all-entities/Program.cs | 1 + .../querying/loading-single-entity/Program.cs | 2 +- 18 files changed, 92 insertions(+), 51 deletions(-) diff --git a/content/efcore/getting-started/manipulating-entities.md b/content/efcore/getting-started/manipulating-entities.md index f8b0e3e..2747674 100644 --- a/content/efcore/getting-started/manipulating-entities.md +++ b/content/efcore/getting-started/manipulating-entities.md @@ -31,7 +31,7 @@ Notice that we do not specify the `Id` property before adding the author to the ## Adding Related Data -In the previous example, we added an author without any books to the database. Now we want to add an author and their books to the database. To add related entities like this to the database using EF Core we simply call the `Add` method on the parent entity. It will then automatically add the parent’s related entities to the database. In the following example, we add an author and their books to the database by simply adding the author: +In the previous example, we added an author without any books to the database. Now we want to add an author and their books to the database. To add related entities like this to the database using EF Core we simply call the `Add` method on the parent entity. It will then automatically add the parent’s related entities to the database. In the following example, we add a new author and their books to the database by simply adding the author: ```{.snippet} using (var context = new LibraryContext()) @@ -81,13 +81,15 @@ using (var context = new LibraryContext()) ## Updating Entities in a Database -Next, let's look at how to update records that are already in the database. In the following example, we update the title of the first book in the database: +Next, let's look at how to update records that are already in the database. For example, we might discover that one of our books was catalogued incorrectly. _Mrs Dalloway_ should be _To the Lighthouse_. To fix this, we update the title and publication year of the book: ```{.snippet} using (var context = new LibraryContext()) { - var book = context.Books.First(); - book.Title = "Frankenstein: or, The Modern Prometheus"; + var book = context.Books + .Single(b => b.Title == "Mrs Dalloway"); + book.Title = "To the Lighthouse"; + book.PublicationYear = 1927; context.SaveChanges(); } ``` @@ -96,19 +98,20 @@ using (var context = new LibraryContext()) Notice we did not have to tell EF Core that the entity had been changed to update its values. This is because the book we retrieved from the database is a **tracked entity**, meaning EF Core will keep track of any changes made to it. EF Core will continue to track changes made to the entity until the context is disposed, which occurs automatically when leaving the `using` block. To learn more about tracked entities, check out the [Tracking vs. No-Tracking](https://docs.microsoft.com/en-us/ef/core/querying/tracking) page in the docs. -Suppose you want to update an untracked entity. As long as the untracked entity has the same primary key as the record in the database, you can accomplish this using the `DbSet`'s `Update` method. In the following example, we update the book with a primary key of `1`: +Suppose you want to update an untracked entity. As long as the untracked entity has the same primary key as the record in the database, you can accomplish this using the `DbSet`'s `Update` method. In the following example, we update the title, genre, and publication year of the book with an `Id` of 1 without tracking the entity: ```{.snippet} using (var context = new LibraryContext()) { - var book = new Book() + var untrackedBook = new Book() { Id = 1, - Title = "Frankenstein: or, The Modern Prometheus", - Genre = "Science Fiction", - PublicationYear = 1818 + Title = "To the Lighthouse", + Genre = "Literary", + PublicationYear = 1927 }; - context.Books.Update(book); + + context.Books.Update(untrackedBook); context.SaveChanges(); } ``` diff --git a/content/efcore/getting-started/samples/loading-related-data/count-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/count-method/Program.cs index 3e275ed..4e3fa11 100644 --- a/content/efcore/getting-started/samples/loading-related-data/count-method/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/count-method/Program.cs @@ -15,7 +15,7 @@ public static void Main() .Query() .Count(); - Console.WriteLine("Count: {0}", numBooks); + Console.WriteLine("Number of books by {0} {1}: {2}", author.FirstName, author.LastName, numBooks); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs index 3adda8d..62040c2 100644 --- a/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/include-and-then-include-method-chain/Program.cs @@ -13,12 +13,13 @@ public static void Main() .ThenInclude(c => c.Reader) .Include(b => b.Author) .Single(b => b.Title.Contains("Orient Express")); + Console.WriteLine("Book: {0}", book.Title); + Console.WriteLine("Author: {0} {1}", book.Author.FirstName, book.Author.LastName); - Console.WriteLine(String.Format("{0}", book.Title)); Console.WriteLine("Checkout Records:"); foreach (CheckoutRecord checkoutRecord in book.CheckoutRecords) { - Console.WriteLine("{0} {1} - Due {2}", checkoutRecord.Reader.FirstName, checkoutRecord.Reader.LastName, checkoutRecord.DueDate.ToString("MMMM dd, yyyy")); + Console.WriteLine("Checked out by {0} {1} on {2}", checkoutRecord.Reader.FirstName, checkoutRecord.Reader.LastName, checkoutRecord.CheckoutDate.ToString("MMMM dd, yyyy")); } } } diff --git a/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs index 1de4fec..268f8b7 100644 --- a/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/include-method/Program.cs @@ -11,8 +11,10 @@ public static void Main() var book = context.Books .Include(b => b.Author) .Single(b => b.Id == 1); - - Console.WriteLine("{0} - {1} {2}", book.Title, book.Author.FirstName, book.Author.LastName); + + Console.WriteLine("-- Included author with book --"); + Console.WriteLine("Title: {0}", book.Title); + Console.WriteLine("Author: {0} {1}", book.Author.FirstName, book.Author.LastName); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/load-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/load-method/Program.cs index 22a7147..ca43954 100644 --- a/content/efcore/getting-started/samples/loading-related-data/load-method/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/load-method/Program.cs @@ -9,15 +9,19 @@ public static void Main() { var author = context.Authors .Single(a => a.LastName == "Twain"); - + + Console.WriteLine("-- Eagerly Loaded Author --"); + Console.WriteLine("{0} {1}", author.FirstName, author.LastName); + context.Entry(author) .Collection(a => a.Books) .Load(); - - foreach (Book book in author.Books) - { - Console.WriteLine(book.Title); - } + + Console.WriteLine("-- Explicitly loaded the author's books --"); + foreach (Book book in author.Books) + { + Console.WriteLine(book.Title); + } } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/max-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/max-method/Program.cs index 83f9a16..91ce0e9 100644 --- a/content/efcore/getting-started/samples/loading-related-data/max-method/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/max-method/Program.cs @@ -16,7 +16,7 @@ public static void Main() .Query() .Max(c => c.CheckoutDate); - Console.WriteLine("Earliest Checkout: {0}", mostRecentCheckout.ToString("MMMM dd, yyyy")); + Console.WriteLine("Most Recent Checkout: {0}", mostRecentCheckout.ToString("MMMM dd, yyyy")); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs index 8781e6b..dfa9b49 100644 --- a/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/multiple-include-methods/Program.cs @@ -13,9 +13,14 @@ public static void Main() .Include(b => b.Author) .Single(b => b.Id == 1); + Console.WriteLine("-- Included author and checkout record(s) with book --"); + Console.WriteLine("Title: {0}", book.Title); + Console.WriteLine("Author: {0} {1}", book.Author.FirstName, book.Author.LastName); + + Console.WriteLine("Checkout Records:"); foreach (CheckoutRecord checkoutRecord in book.CheckoutRecords) { - Console.WriteLine("{0}: {1} {2}, Due {3}", checkoutRecord.Book.Title, book.Author.FirstName, book.Author.LastName, checkoutRecord.DueDate.ToString("MMMM dd, yyyy")); + Console.WriteLine("Checked out by {0} {1} on {2}", checkoutRecord.Reader.FirstName, checkoutRecord.Reader.LastName, checkoutRecord.CheckoutDate.ToString("MMMM dd, yyyy")); } } } diff --git a/content/efcore/getting-started/samples/loading-related-data/query-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/query-method/Program.cs index a993e7a..cf11cc7 100644 --- a/content/efcore/getting-started/samples/loading-related-data/query-method/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/query-method/Program.cs @@ -11,12 +11,16 @@ public static void Main() var author = context.Authors .Single(a => a.LastName == "Twain"); + Console.WriteLine("-- Eagerly loaded author --") + Console.WriteLine("{0} {1}", author.FirstName, author.LastName); + context.Entry(author) .Collection(a => a.Books) .Query() .Where(b => b.Title.Contains("Huck")) .Load(); + Console.WriteLine("-- Explicitly loaded the author's books containing \"Huck\" --"); foreach (var book in author.Books) { Console.WriteLine(book.Title); diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs index 8d2692a..50a8722 100644 --- a/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method-chain/Program.cs @@ -16,9 +16,11 @@ public static void Main() foreach (Book book in author.Books) { + Console.WriteLine("Book: {0}", book.Title); + Console.WriteLine("Checkout Records:"); foreach (CheckoutRecord checkoutRecord in book.CheckoutRecords) { - Console.WriteLine("{0}: Due {1} - {2} {3}", book.Title, checkoutRecord.DueDate.ToString("MMMM dd, yyyy"), checkoutRecord.Reader.FirstName, checkoutRecord.Reader.LastName); + Console.WriteLine("Checked out by {0} {1} on {2}", checkoutRecord.Reader.FirstName, checkoutRecord.Reader.LastName, checkoutRecord.CheckoutDate.ToString("MMMM dd, yyyy")); } } } diff --git a/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs b/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs index bd41cf6..d1b6697 100644 --- a/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs +++ b/content/efcore/getting-started/samples/loading-related-data/then-include-method/Program.cs @@ -11,11 +11,15 @@ public static void Main() var book = context.Books .Include(b => b.CheckoutRecords) .ThenInclude(c => c.Reader) - .Single(b => b.Id == 1); + .Single(b => b.Id == 1); + Console.WriteLine("-- Included checkout record(s) and associated reader with book --"); + Console.WriteLine("Title: {0}", book.Title); + + Console.WriteLine("Checkout Records:", book.Title); foreach (CheckoutRecord checkoutRecord in book.CheckoutRecords) { - Console.WriteLine("{0} - {1} {2}", checkoutRecord.Book.Title, checkoutRecord.Reader.FirstName, checkoutRecord.Reader.LastName); + Console.WriteLine("Checked out by {0} {1} on {2}", checkoutRecord.Reader.FirstName, checkoutRecord.Reader.LastName, checkoutRecord.CheckoutDate.ToString("MMMM dd, yyyy")); } } } diff --git a/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs index 6968507..f9b30ae 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs +++ b/content/efcore/getting-started/samples/manipulating-entities/add-new-entity-to-existing/Program.cs @@ -26,7 +26,9 @@ public static void Main() .Include(b => b.Author) .Single(b => b.Title.Contains("Badge")); - Console.WriteLine("{0}: {1}, {2} {3}", addedBook.Id, addedBook.Title, addedBook.Author.FirstName, addedBook.Author.LastName); + Console.WriteLine("-- Added new book to existing author --"); + Console.WriteLine("Book: {0}", addedBook.Title); + Console.WriteLine("Author: {0} {1}", author.FirstName, author.LastName); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs index d3cc452..e6b0d26 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-entities/Program.cs @@ -18,7 +18,7 @@ public static void Main() var addedAuthor = context.Authors .Single(a => a.LastName.Contains("Shelley")); - Console.WriteLine("{0}: {1} {2}", addedAuthor.Id, addedAuthor.FirstName, addedAuthor.LastName); + Console.WriteLine("New Author: {0} {1}", addedAuthor.FirstName, addedAuthor.LastName); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/Program.cs index 07715b1..841deb5 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/Program.cs +++ b/content/efcore/getting-started/samples/manipulating-entities/adding-related-entities/Program.cs @@ -28,9 +28,12 @@ public static void Main() var addedAuthor = context.Authors .Include(a => a.Books) .Single(a => a.LastName.Contains("Shelley")); - + + Console.WriteLine("-- Added author and associated books --"); + Console.WriteLine("Author: {0} {1}", addedAuthor.FirstName, addedAuthor.LastName); + Console.WriteLine("Books:"); foreach (Book book in addedAuthor.Books) { - Console.WriteLine("{0} - {1}, {2}", book.Title, book.Genre, book.PublicationYear); + Console.WriteLine(book.Title); } } } diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs index 2ced383..c75d120 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-entities/Program.cs @@ -7,19 +7,24 @@ public static void Main() { using (var context = new LibraryContext()) { - var book = context.Books.First(); + var book = context.Books + .Single(b => b.Title == "Mrs Dalloway"); - Console.WriteLine(String.Format("Original Book - {0}: {1}", book.Id, book.Title)); + Console.WriteLine("-- Original Book --"); + Console.WriteLine("Id: {0}", book.Id); + Console.WriteLine("Title: {0}", book.Title); + Console.WriteLine("Genre: {0}", book.Genre); + Console.WriteLine("Publication Year: {0}", book.PublicationYear); - book.Title = "Frankenstein: or, The Modern Prometheus"; - context.SaveChanges(); - } - - using (var context = new LibraryContext()) { - var updatedBook = context.Books - .Single(b => b.Title.Contains("Frankenstein")); - - Console.WriteLine(String.Format("Updated Book - {0}: {1}", updatedBook.Id, updatedBook.Title)); + book.Title = "To the Lighthouse"; + book.PublicationYear = 1927; + context.SaveChanges(); + + Console.WriteLine("\n-- Updated Book --"); + Console.WriteLine("Id: {0}", book.Id); + Console.WriteLine("Title: {0}", book.Title); + Console.WriteLine("Genre: {0}", book.Genre); + Console.WriteLine("Publication Year: {0}", book.PublicationYear); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs index a72c816..1188400 100644 --- a/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs +++ b/content/efcore/getting-started/samples/manipulating-entities/updating-untracked-entities/Program.cs @@ -7,21 +7,25 @@ public static void Main() { using (var context = new LibraryContext()) { - var untrackedBook = new Book() + var untrackedBook = new Book() { - Id = 1, - Title = "Frankenstein: or, The Modern Prometheus", - Genre = "Science Fiction", - PublicationYear = 1818 + Id = 1, + Title = "To the Lighthouse", + Genre = "Literary", + PublicationYear = 1927 }; - - context.Books.Update(untrackedBook); + + context.Books.Update(untrackedBook); context.SaveChanges(); var updatedBook = context.Books .Single(b => b.Id == 1); - Console.WriteLine("{0}: {1}, {2} {3}", updatedBook.Id, updatedBook.Title, updatedBook.Genre, updatedBook.PublicationYear); + Console.WriteLine("-- Updated Book --"); + Console.WriteLine("Id: {0}", updatedBook.Id); + Console.WriteLine("Title: {0}", updatedBook.Title); + Console.WriteLine("Genre: {0}", updatedBook.Genre); + Console.WriteLine("Publication Year: {0}", updatedBook.PublicationYear); } } } \ No newline at end of file diff --git a/content/efcore/getting-started/samples/querying/filtering-entities/Program.cs b/content/efcore/getting-started/samples/querying/filtering-entities/Program.cs index 1e05ed9..59d49a8 100644 --- a/content/efcore/getting-started/samples/querying/filtering-entities/Program.cs +++ b/content/efcore/getting-started/samples/querying/filtering-entities/Program.cs @@ -12,9 +12,10 @@ public static void Main() .Where(b => b.Genre == "Historical") .ToList(); + Console.WriteLine("Historical books in library:"); foreach (Book book in books) { - Console.WriteLine(String.Format("{0} - {1}", book.Title, book.Genre)); + Console.WriteLine(book.Title); } } } diff --git a/content/efcore/getting-started/samples/querying/loading-all-entities/Program.cs b/content/efcore/getting-started/samples/querying/loading-all-entities/Program.cs index 3106389..4bc57f5 100644 --- a/content/efcore/getting-started/samples/querying/loading-all-entities/Program.cs +++ b/content/efcore/getting-started/samples/querying/loading-all-entities/Program.cs @@ -9,6 +9,7 @@ public static void Main() using (var context = new LibraryContext()) { var books = context.Books.ToList(); + Console.WriteLine("Books in library:"); foreach (Book book in books) { Console.WriteLine(book.Title); diff --git a/content/efcore/getting-started/samples/querying/loading-single-entity/Program.cs b/content/efcore/getting-started/samples/querying/loading-single-entity/Program.cs index 3ebb086..949b53a 100644 --- a/content/efcore/getting-started/samples/querying/loading-single-entity/Program.cs +++ b/content/efcore/getting-started/samples/querying/loading-single-entity/Program.cs @@ -10,7 +10,7 @@ public static void Main() { var book = context.Books .Single(b => b.Id == 1); - Console.WriteLine(book.Title); + Console.WriteLine("First book: {0}", book.Title); } } } \ No newline at end of file From 964139c5affb1c984af4a356151f840b2c7c8abe Mon Sep 17 00:00:00 2001 From: Ryan Helmoski Date: Mon, 24 Apr 2017 16:34:10 -0500 Subject: [PATCH 55/56] Resolves #67 - Explains multifile functionality in README.md --- README.md | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 75dab6e..f47e944 100644 --- a/README.md +++ b/README.md @@ -21,14 +21,113 @@ Lessons will include *tips* that will be tagged according to reader background, Lessons will also include *notes*, which will receive special formatting when displayed to readers. For example: -### Note {.note} +> **Note** {.note} > It is common to log exceptions that occur, so that you can review them later and improve the program to avoid them, if possible. Lessons will be written using [markdown (Github variant)](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). Lessons should link to other documents for specific tasks and API references. These should focus on helping the user follow through and understand the tutorial. +## Code Examples + +There are three types of code examples used throughout the tutorials: + + * Non-runnable + * Single-file runnable + * Multi-file runnable + +Runnable code examples are preferred over non-runnable code examples. + +### Non-runnable + +Non-runnable code examples should be formatted like so: + + ```{C#} + Console.WriteLine("Hello World"); + ``` + +### Single-file Runnable + +Single-file runnable code examples should be formatted like so: + + ```{.snippet} + Console.WriteLine("Hello World"); + ``` + ```{.REPL} + using System; + + public class Program + { + public static void Main() + { + Console.WriteLine("Hello World"); + } + } + ``` + +The `.snippet` code block will be displayed in the lesson content with a "Show Me" button that, when clicked, will open up the console editor with the content of the `.REPL` block, which will not be displayed in the lesson content. Only code relevant to what is being discussed in the lesson should be placed in the `.snippet` block, and all of the code necessary to run the example should be included in the `.REPL` block. + +### Multi-file Runnable + +Multi-file runnable code examples should be formatted like so: + + ```{.snippet} + var greeter = new Greeter(); + greeter.greet(); + ``` + :::repl{data-name=greeter} + ::: + +The `.snippet` code block will be displayed in the lesson content with a "Show Me" button that, when clicked, will open up the console editor with the content of the multi-file code example that has the name specified by "data-name". The code files associated with the example should be located within the `training-tutorials` repo in `content/{topic}/{tutorial}/samples/{lesson}/{example}`. This directory should also contain a `README.md` that contains a description of the code example, as well as a list of the files necessary for that example. + +For example, the loading-all-entities code example for the querying lesson in the efcore getting-started tutorial is organized like so: + +``` +content +| +|--efcore + | + |--getting-started + | + |--samples + | + |--querying + | | + | |--loading-all-entities + | | + | |--Program.cs + | |--README.md + | + |--shared + | + |--Address.cs + |--Author.cs + |--Book.cs + |--CheckoutRecord.cs + |--LibraryContext.cs + |--Reader.cs +``` + +The associated `README.md` file is formatted like so: + +```{Markdown} +# Loading All Entities + +This code example demonstrates how to use EF Core to query all entities from the database. + +## Code Files: +- [Program.cs](Program.cs) +- [Book.cs](../../shared/Book.cs) +- [LibraryContext.cs](../../shared/LibraryContext.cs) +- [Author.cs](../../shared/Author.cs) +- [CheckoutRecord.cs](../../shared/CheckoutRecord.cs) +- [Reader.cs](../../shared/Reader.cs) +- [Address.cs](../../shared/Address.cs) +``` + +It is important that the `Code Files` section be formatted exactly as shown here because `dotnet-core-website` parses this list to find the files necessary for the code example. + ## Includes / Shared Elements -The ultimately publishing platform capabilities and requirements aren't yet known. Until they are, we don't have a system in place for includes or for sharing common elements across tutorials/pages. For now, we'll need to copy/paste. +The ultimate publishing platform capabilities and requirements aren't yet known. Until they are, we don't have a system in place for includes or for sharing common elements across tutorials/pages. For now, we'll need to copy/paste. ## Branching Strategy From fdd875e6d45b2753987f8fc0404086d33a671a7a Mon Sep 17 00:00:00 2001 From: Ryan Helmoski Date: Tue, 25 Apr 2017 20:14:21 -0500 Subject: [PATCH 56/56] Resolves #111 - One-to-one Relationship Example Bug --- .../one-to-one-manual-foreign-key/README.md | 2 +- .../{shared => one-to-one-manual-foreign-key}/Reader.cs | 0 .../one-to-one-relationship/README.md | 2 +- .../one-to-one-relationship/Reader.cs | 8 ++++++++ 4 files changed, 10 insertions(+), 2 deletions(-) rename content/efcore/getting-started/samples/defining-entity-relationships/{shared => one-to-one-manual-foreign-key}/Reader.cs (100%) create mode 100644 content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/Reader.cs diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md index 1fbeb50..db6225f 100644 --- a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/README.md @@ -5,5 +5,5 @@ This code example demonstrates how to create a one-to-one relationship in EF Cor ## Code Files: - [LibraryContext.cs](LibraryContext.cs) - [Address.cs](../shared/Address.cs) -- [Reader.cs](../shared/Reader.cs) +- [Reader.cs](Reader.cs) - [Program.cs](../shared/Program.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/shared/Reader.cs b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/Reader.cs similarity index 100% rename from content/efcore/getting-started/samples/defining-entity-relationships/shared/Reader.cs rename to content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-manual-foreign-key/Reader.cs diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md index d69cb34..c47ba1b 100644 --- a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/README.md @@ -3,7 +3,7 @@ This code example demonstrates how to create a one-to-one relationship in EF Core using navigation properties. ## Code Files: -- [Reader.cs](../shared/Reader.cs) +- [Reader.cs](Reader.cs) - [Address.cs](../shared/Address.cs) - [LibraryContext.cs](LibraryContext.cs) - [Program.cs](../shared/Program.cs) \ No newline at end of file diff --git a/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/Reader.cs b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/Reader.cs new file mode 100644 index 0000000..d8017ab --- /dev/null +++ b/content/efcore/getting-started/samples/defining-entity-relationships/one-to-one-relationship/Reader.cs @@ -0,0 +1,8 @@ +public class Reader +{ + public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + + public Address Address { get; set; } +} \ No newline at end of file