<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>entity framework tutorial &#8211; ASP.NET Hosting Reviews and Guides</title>
	<atom:link href="https://topreviewhostingasp.net/tag/entity-framework-tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>https://topreviewhostingasp.net</link>
	<description>ASP.NET Hosting &#124; Reviews &#124; Tips &#38; Tutorial</description>
	<lastBuildDate>Wed, 08 Feb 2023 06:41:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://topreviewhostingasp.net/wp-content/uploads/2017/01/cropped-trhaico-32x32.png</url>
	<title>entity framework tutorial &#8211; ASP.NET Hosting Reviews and Guides</title>
	<link>https://topreviewhostingasp.net</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>How to Build CRUD REST APIs with ASP.NET Core 3.1 and Entity Framework</title>
		<link>https://topreviewhostingasp.net/how-to-build-crud-rest-apis-with-asp-net-core-3-1-and-entity-framework/</link>
					<comments>https://topreviewhostingasp.net/how-to-build-crud-rest-apis-with-asp-net-core-3-1-and-entity-framework/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Wed, 08 Feb 2023 05:22:40 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[asp net core]]></category>
		<category><![CDATA[asp net core tips]]></category>
		<category><![CDATA[asp net core tutorial]]></category>
		<category><![CDATA[entity framework]]></category>
		<category><![CDATA[entity framework tips]]></category>
		<category><![CDATA[entity framework tutorial]]></category>
		<category><![CDATA[jwt tokens asp net core]]></category>
		<category><![CDATA[rest api]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3387</guid>

					<description><![CDATA[In this blog, I am going to provide a walkthrough on developing REST APIs using ASP.NET Core 3.1, connecting with existing databases using Entity Framework, creating a JWT token, and securing APIs. I am going to develop a sample application for an inventory REST service with basic operations. What is a REST API? Due to [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In this blog, I am going to provide a walkthrough on developing REST APIs using ASP.NET Core 3.1, connecting with existing databases using Entity Framework, creating a JWT token, and securing APIs. I am going to develop a sample application for an inventory REST service with basic operations.</p>



<h2 class="wp-block-heading" id="what-is-a-REST-API">What is a REST API?</h2>



<p>Due to the increasing number of different varieties of clients (mobile apps, browser-based SPAs, desktop apps, IOT apps, etc.), we need better ways for transferring data from servers to clients, independent of technology and server stacks.</p>



<p>REST APIs solve this problem. REST stands for representational state transfer. REST APIs are HTTP-based and provide applications the ability to communicate using lightweight JSON format. They run on web servers.</p>



<p>REST consists of the following entities:</p>



<p><strong>Resource</strong>: Resources are uniquely identifiable entities (for example: data from a database, images, or any data).</p>



<p><strong>Endpoint</strong>: A resource can be accessed through a <strong>URL</strong> identifier.</p>



<p><strong>HTTP method</strong>: HTTP method is the type of request a client sends to a server. Operations we perform on the resource should follow this.</p>



<p><strong>HTTP header</strong>: An HTTP header is a key-value pair used to share additional information between a client and server, such as:</p>



<ul>
<li>Type of data being sent to server (JSON, XML).</li>
<li>Type of encryption supported by client.</li>
<li>Authentication-related token.</li>
<li>Customer data based on application need.</li>
</ul>



<p><strong>Data format</strong>: JSON is a common format to send and receive data through REST APIs.</p>



<h2 class="wp-block-heading" id="what-is-a-JWT-Token">What is a JWT Token?</h2>



<p>In the previous section, we saw what a REST API is, and here we will see what a JWT bearer token is, which secures the REST APIs.</p>



<p>JWT stands for JSON Web Token. It is open standard and defines a better way for transferring data securely between two entities (client and server).</p>



<p>A JWT is digitally signed using a secret key by a token provider or authentication server. A JWT helps the resource server verify the token data using the same secret key, so that you can trust the data.</p>



<p>JWT consists of the following three parts:</p>



<p><strong>Header</strong>: encoded data of token type and the algorithm used to sign the data.</p>



<p><strong>Payload</strong>: encoded data of claims intended to share.</p>



<p><strong>Signature</strong>: created by signing (encoded header + encoded payload) using a secret key.</p>



<p>The final JWT token will be like this: <strong>Header.Payload.Signature. </strong>Please find the token workflow in the following.</p>



<p><strong>Step 1: Client requesting token</strong></p>



<p>The client sends a request to the authentication server with the necessary information to prove its identity.</p>



<p><strong>Step 2: Token creation</strong></p>



<p>The authentication server receives the token request and verifies the identity. If it is found valid, a token will be created (as explained previously) with the necessary claims, and a JWT token will be sent back to the client.</p>



<p><strong>Step 3: Client sends token to resource server</strong></p>



<p>For each request to Resource or the API server, the client needs to include a token in the header and request the resource using its URI.</p>



<p><strong>Step 4: Resource server verifies the token</strong></p>



<p>Follow these steps to verify the token:</p>



<ul>
<li>Read the token from authentication header.</li>
<li>Split the header, payload, and signature from token.</li>
<li>Create signature of received header and payload using the same secret key used when creating the token.</li>
<li>Check whether both newly created signature and signature received from token are valid.</li>
<li>If the signatures are the same, the tokens are valid (not altered in the middle) and they provide access to the requested resource.</li>
<li>If the signatures are different, an <strong>unauthorized</strong> response will be sent back to the client. (In the middle, if claims are alerted, they will generate a different signature, hence resource access will be restricted.)</li>
</ul>



<p>Don’t share confidential information using a JWT, since a JWT can be decoded and the claims or data it possesses can be viewed.</p>



<p>The following section explains how to create a REST API and secure it using a token.</p>



<h2 class="wp-block-heading" id="create-an-ASP-NET-Core-REST-API-application">Create an ASP.NET Core REST API application</h2>



<p>Follow these steps to create an ASP.NET Core application in Visual Studio 2019:</p>



<p><strong>Step 1:</strong> Go to <strong>File</strong> &gt; <strong>New</strong>, and then select <strong>Project.</strong></p>



<p><strong>Step 2:</strong> Choose <strong>Create a new project</strong>.</p>



<p><strong>Step 3: </strong>Select <strong>ASP.NET Core Web Application</strong> template.</p>



<p><strong>Step 4:</strong>  Enter the <strong>Project name</strong>, and then click <strong>Create</strong>. The Project template dialog will be displayed.</p>



<p><strong>Step 5:</strong> Select <strong>.NET Core,</strong> <strong>ASP.NET Core 3.1</strong>, and <strong>API</strong> template (highlighted in the following).</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="593" class="wp-image-3388" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/asp-net-core-3-1024x593.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/asp-net-core-3-1024x593.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/asp-net-core-3-300x174.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/asp-net-core-3-768x445.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/asp-net-core-3-50x29.png 50w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/asp-net-core-3.png 1188w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>Step 6: </strong>Click <strong>Create</strong>. The sample ASP.NET Core API application will be created. Find the project structure in the following screenshot.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="302" height="218" class="wp-image-3390" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-project-structure-1.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-project-structure-1.png 302w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-project-structure-1-300x217.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-project-structure-1-50x36.png 50w" sizes="(max-width: 302px) 100vw, 302px" /></figure></div>


<p>By default, a sample <strong>WeatherForecast</strong> API is created. We can remove this.</p>



<h2 class="wp-block-heading" id="install-necessary-NuGet-packages">Install necessary NuGet packages</h2>



<p>Add the following NuGet packages to work with SQL Server database and scaffolding, and run the following commands in <strong>Package Manager Console </strong>(Click <strong>Tools -&gt; NuGet Package Manager -&gt;  Package Manager Console</strong>).</p>



<p>This package helps generate controllers and views.</p>



<ul>
<li><strong>Install-Package Microsoft.VisualStudio.Web.CodeGeneration.Design -Version 3.1.4</strong></li>
</ul>



<p>This package helps create database context and model classes from the database.</p>



<ul>
<li><strong>Install-Package Microsoft.EntityFrameworkCore.Tools -Version 3.1.8</strong></li>
</ul>



<p>Database provider allows Entity Framework Core to work with SQL Server.</p>



<ul>
<li><strong>Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 3.1.8</strong></li>
</ul>



<p>It provides support for creating and validating a JWT token.</p>



<ul>
<li><strong>Install-Package System.</strong><strong>IdentityModel.Tokens.Jwt</strong> <strong>-Version 5.6.0</strong></li>
</ul>



<p>This is the middleware that enables an ASP.NET Core application to receive a bearer token in the request pipeline.</p>



<ul>
<li><strong>Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 3.1.8</strong></li>
</ul>



<h2 class="wp-block-heading" id="create-database-and-connect-it-to-application">Create database and connect it to application</h2>



<p>I hope you have installed SQL Server 2017 in your machine. (You can also use SQL Server 2008, 2012, or 2016.)</p>



<p><strong>Step 1</strong>: Create a new database (<strong>Inventory</strong>).</p>



<p><strong>Step 2</strong>: For this application, I am going to create tables called <strong>Products</strong> and<strong> UserInfo</strong> with basic attributes. Paste the following SQL query into the Query window to create necessary tables.</p>



<pre class="wp-block-code"><code>Create Table Products(
ProductId Int Identity(1,1) Primary Key,
Name Varchar(100) Not Null,
Category Varchar(100),
Color Varchar(20),
UnitPrice Decimal Not Null,
AvailableQuantity Int Not Null)
GO
Create Table UserInfo(
UserId Int Identity(1,1) Not null Primary Key,
FirstName Varchar(30) Not null,
LastName Varchar(30) Not null,
UserName Varchar(30) Not null,
Email Varchar(50) Not null,
Password Varchar(20) Not null,
CreatedDate DateTime Default(GetDate()) Not Null)
GO
Insert Into UserInfo(FirstName, LastName, UserName, Email, Password) 
Values ('Inventory', 'Admin', 'InventoryAdmin', 'InventoryAdmin@abc.com', '$admin@2017')</code></pre>



<p><strong>Step 3:</strong> Run the following scaffold command in <strong>Package Manager Console</strong> to reverse engineer the database to create database context and entity POCO classes from tables. The scaffold command will create POCO class only for the tables that have a primary key.</p>



<p><strong>Scaffold-DbContext “Server=******;Database=Inventory;Integrated Security=True” Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models</strong></p>



<ul>
<li><strong>Connection</strong>: Sets connection string of the database.</li>
<li><strong>Provider</strong>: Sets the provider to be used to connect database.</li>
<li><strong>OutputDir</strong>: Sets the directory where the POCO classes are generated.</li>
</ul>



<p>In our case, the Products class and Inventory context class will be created as shown in the following screenshot.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="269" height="276" class="wp-image-3392" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/inventory-context-class-1.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/inventory-context-class-1.png 269w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/inventory-context-class-1-50x50.png 50w" sizes="(max-width: 269px) 100vw, 269px" /></figure></div>


<p>In the autogenerated <strong>InventoryContext</strong> class file, the database credentials you can see are hard coded in the <strong>OnConfiguring</strong> method. It is not a good practice to have SQL Server credentials in C# class, considering the security issues. So, remove the following <strong>OnConfiguring</strong> method and <strong>parameterless</strong> <strong>constructor</strong> from context file (highlighted).</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="679" height="507" class="wp-image-3394" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Removing-the-OnConfiguring-method-and-parameterless-constructor-from-context-file-1.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Removing-the-OnConfiguring-method-and-parameterless-constructor-from-context-file-1.png 679w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Removing-the-OnConfiguring-method-and-parameterless-constructor-from-context-file-1-300x224.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Removing-the-OnConfiguring-method-and-parameterless-constructor-from-context-file-1-50x37.png 50w" sizes="(max-width: 679px) 100vw, 679px" /></figure></div>


<p>Add a connection string to the <strong>appsetting.json</strong> file.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="859" height="276" class="wp-image-3395" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Adding-a-connection-string-to-the-appsetting.json-file.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Adding-a-connection-string-to-the-appsetting.json-file.png 859w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Adding-a-connection-string-to-the-appsetting.json-file-300x96.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Adding-a-connection-string-to-the-appsetting.json-file-768x247.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Adding-a-connection-string-to-the-appsetting.json-file-50x16.png 50w" sizes="(max-width: 859px) 100vw, 859px" />
<figcaption>Then, register the database context service (<strong>InventoryContext</strong>) during application startup. In the following code, the connection string is read from the <strong>appsetting</strong> file and is passed to the context service.</figcaption>
</figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="855" height="124" class="wp-image-3396" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Register-the-database-context-service-during-application-startup.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Register-the-database-context-service-during-application-startup.png 855w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Register-the-database-context-service-during-application-startup-300x44.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Register-the-database-context-service-during-application-startup-768x111.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Register-the-database-context-service-during-application-startup-50x7.png 50w" sizes="(max-width: 855px) 100vw, 855px" />
<figcaption>Add the following namespaces to the startup file:</figcaption>
</figure>



<pre class="wp-block-code"><code>using InventoryService.Models;
using Microsoft.EntityFrameworkCore;</code></pre>



<p>Then this context service is injected with the required controllers via dependency injection.</p>



<h2 class="wp-block-heading" id="build-REST-APIs">Build REST APIs</h2>



<p>Now, we have database and entity classes in place. Follow these steps to create <strong>Products API</strong>:</p>



<p><strong>Step 1: </strong>Right<strong>–</strong>click the <strong>Controllers</strong> folder, choose <strong>Add</strong>, and then click <strong>Controller</strong>.</p>



<p><strong>Step 2: </strong>Select <strong>API</strong> <strong>Controller with actions</strong> using the <strong>Entity Framework </strong>template.</p>



<p><strong>Step 3</strong>: Choose the <strong>Products</strong> model class and <strong>InventoryContext </strong>context class, and then name the control<strong> ProductsController</strong>.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="735" height="263" class="wp-image-3398" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-the-Products-model-class-and-InventoryContext-context-class-and-naming-the-control-ProductsController-1.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-the-Products-model-class-and-InventoryContext-context-class-and-naming-the-control-ProductsController-1.png 735w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-the-Products-model-class-and-InventoryContext-context-class-and-naming-the-control-ProductsController-1-300x107.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-the-Products-model-class-and-InventoryContext-context-class-and-naming-the-control-ProductsController-1-50x18.png 50w" sizes="(max-width: 735px) 100vw, 735px" /></figure>



<p>When we click <strong>Add</strong>, the API is automatically created using the <strong>ASP.NET CORE scaffolding</strong> code generation technique.</p>



<p>The following APIs are created:</p>



<ul>
<li>To list all products: HTTP Get method</li>
<li>Get product detail: HTTP Get method</li>
<li>Update product detail: HTTP Put method</li>
<li>Create product: HTTP Post method</li>
<li>Delete product: HTTP Delete method</li>
</ul>



<p>As per REST best practice, each endpoint is assigned with respective <strong>HTTP methods</strong> based on its operation.</p>



<pre class="wp-block-code"><code>using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using InventoryService.Models;
using Microsoft.AspNetCore.Authorization;

namespace InventoryService.Controllers
{
    [Authorize]
    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        private readonly InventoryContext _context;

        public ProductsController(InventoryContext context)
        {
            _context = context;
        }

        [HttpGet]
        public async Task&lt;ActionResult&lt;IEnumerable&lt;Products&gt;&gt;&gt; GetProducts()
        {
            return await _context.Products.ToListAsync();
        }


        // GET: api/Products/5
        [HttpGet("{id}")]
        public async Task&lt;ActionResult&lt;Products&gt;&gt; GetProducts(int id)
        {
            var products = await _context.Products.FindAsync(id);

            if (products == null)
            {
                return NotFound();
            }

            return products;
        }

        // PUT: api/Products/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        [HttpPut("{id}")]
        public async Task&lt;IActionResult&gt; PutProducts(int id, Products products)
        {
            if (id != products.ProductId)
            {
                return BadRequest();
            }

            _context.Entry(products).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ProductsExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

        // POST: api/Products
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for
        // more details see https://aka.ms/RazorPagesCRUD.
        [HttpPost]
        public async Task&lt;ActionResult&lt;Products&gt;&gt; PostProducts(Products products)
        {
            _context.Products.Add(products);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetProducts", new { id = products.ProductId }, products);
        }

        // DELETE: api/Products/5
        [HttpDelete("{id}")]
        public async Task&lt;ActionResult&lt;Products&gt;&gt; DeleteProducts(int id)
        {
            var products = await _context.Products.FindAsync(id);
            if (products == null)
            {
                return NotFound();
            }

            _context.Products.Remove(products);
            await _context.SaveChangesAsync();

            return products;
        }

        private bool ProductsExists(int id)
        {
            return _context.Products.Any(e =&gt; e.ProductId == id);
        }
    }
}</code></pre>



<p>Now, we are going to make the following modifications to the <strong>Get Products API</strong> to filter the products:</p>



<ul>
<li>Return the products that are in stock.</li>
<li>Support limiting the number of results returned.</li>
</ul>



<pre class="wp-block-code"><code>[HttpGet]
        public async Task&lt;ActionResult&lt;IEnumerable&lt;Products&gt;&gt;&gt; GetProducts(bool? inStock, int? skip, int? take)
        {
            var products = _context.Products.AsQueryable();

            if (inStock != null) // Adds the condition to check availability 
            {
                products = _context.Products.Where(i =&gt; i.AvailableQuantity &gt; 0);
            }

            if (skip != null)
            {
                products = products.Skip((int)skip);
            }

            if (take != null)
            {
                products = products.Take((int)take);
            }

            return await products.ToListAsync();
        }</code></pre>



<p>Change the launch URL to <strong>api/products</strong> in launchSettings.js.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="454" height="161" class="wp-image-3400" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Changing-the-launch-URL-to-API-or-products-in-launchSettings.js-1.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Changing-the-launch-URL-to-API-or-products-in-launchSettings.js-1.png 454w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Changing-the-launch-URL-to-API-or-products-in-launchSettings.js-1-300x106.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Changing-the-launch-URL-to-API-or-products-in-launchSettings.js-1-50x18.png 50w" sizes="(max-width: 454px) 100vw, 454px" /></figure></div>


<h2 class="wp-block-heading" id="run-and-test-APIs-using-Postman">Run and test APIs using Postman</h2>



<p>Click <strong>Run</strong> to view the Inventory service.  A new browser tab will open, and we’ll be able to see the product listing.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="444" height="524" class="wp-image-3401" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Viewing-the-Inventory-service.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Viewing-the-Inventory-service.png 444w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Viewing-the-Inventory-service-254x300.png 254w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Viewing-the-Inventory-service-42x50.png 42w" sizes="(max-width: 444px) 100vw, 444px" /></figure></div>


<p>Our Inventory REST service is up and running.</p>



<p><strong>Note:</strong> The localhost port number may be different in your development machine.</p>



<p>In this section, we will see how to consume our service using Postman (<strong>Postman is an API testing tool that helps developers consume and check how an API works</strong>).</p>



<p>Follow these steps to view the products list:</p>



<p><strong>Step 1</strong>: Open Postman and enter this endpoint: https://localhost:44305/api/products.</p>



<p><strong>Step 2</strong>: Choose the <strong>GET</strong> method and click <strong>Send</strong>. Now, all the products will be listed as shown in the following screenshot.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="905" height="859" class="wp-image-3402" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Listing-all-the-products.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Listing-all-the-products.png 905w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Listing-all-the-products-300x285.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Listing-all-the-products-768x729.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Listing-all-the-products-50x47.png 50w" sizes="(max-width: 905px) 100vw, 905px" /></figure>



<p>Now, apply the filter to return products that are in stock and fetch only necessary items using skip and take.</p>



<p>Enter the following endpoint into Postman: https://localhost:44305/api/products?instock=true&amp;skip=2&amp;take=3</p>



<p>Now, you can see only the products that are in stock. It skips the first two records and displays the next three records.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="589" height="716" class="wp-image-3404" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Listing-only-the-products-that-are-in-stock-1.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Listing-only-the-products-that-are-in-stock-1.png 589w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Listing-only-the-products-that-are-in-stock-1-247x300.png 247w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Listing-only-the-products-that-are-in-stock-1-41x50.png 41w" sizes="(max-width: 589px) 100vw, 589px" /></figure></div>


<p>Follow these steps to view the details of a product:</p>



<p><strong>Step 1</strong>: Open Postman and enter this endpoint: https://localhost:44305/api/products/1.</p>



<p><strong>Step 2</strong>: Choose <strong>GET</strong> method and click <strong>Send</strong>. Now, you can see the details of the product. Here, the product id is 1.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="454" height="443" class="wp-image-3405" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-details-of-a-product.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-details-of-a-product.png 454w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-details-of-a-product-300x293.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-details-of-a-product-50x50.png 50w" sizes="(max-width: 454px) 100vw, 454px" /></figure></div>


<p><strong>Note:</strong> Change ProductId based on records available in your database.</p>



<p>Follow these steps to update the product:</p>



<p><strong>Step 1</strong>: Enter this endpoint into Postman: https://localhost:44305/api/products/7.</p>



<p><strong>Step 2</strong>: Choose the <strong>PUT</strong> method and set as header: <strong>‘Content-Type’: ‘application/json’</strong>.</p>



<p><strong>Step 3</strong>: Under Body &gt; Raw, choose type <strong>JSON (application/javascript)</strong> and paste the product details.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="661" height="286" class="wp-image-3406" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application-or-javascript-and-paste-the-product-details.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application-or-javascript-and-paste-the-product-details.png 661w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application-or-javascript-and-paste-the-product-details-300x130.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application-or-javascript-and-paste-the-product-details-50x22.png 50w" sizes="(max-width: 661px) 100vw, 661px" /></figure></div>


<p>By clicking <strong>Send</strong>, a product is created, and by loading the product listing page, you can see the newly created product.</p>



<p>Follow these steps to update the product:</p>



<p><strong>Step 1</strong>: Enter this endpoint into Postman: https://localhost:44305/api/products/7.</p>



<p><strong>Step 2</strong>: Choose the <strong>PUT</strong> method and set as header: <strong>‘Content-Type’: ‘application/json’</strong>.</p>



<p><strong>Step 3</strong>: Under Body &gt; Raw, choose type <strong>JSON (application/javascript)</strong> and paste the product details.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="610" height="284" class="wp-image-3407" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application.png 610w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application-300x140.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application-50x23.png 50w" sizes="(max-width: 610px) 100vw, 610px" /></figure></div>


<p>By clicking <strong>Send</strong>, the product details are updated.</p>



<p><strong>Note:</strong> <strong>ProductId</strong> must be the same in the endpoint and product details (see the red highlight in the previous image), otherwise the API will throw bad request.</p>



<p>Follow these steps to delete a product:</p>



<p><strong>Step 1</strong>: Enter this endpoint into Postman: https://localhost:44305/api/products/7.</p>



<p><strong>Step 2</strong>: Choose the <strong>DELETE</strong> method and click <strong>Send</strong>. Now, the product will be deleted from the database.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="592" height="172" class="wp-image-3408" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Deleting-the-product-from-database.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Deleting-the-product-from-database.png 592w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Deleting-the-product-from-database-300x87.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Deleting-the-product-from-database-50x15.png 50w" sizes="(max-width: 592px) 100vw, 592px" /></figure></div>


<h2 class="wp-block-heading" id="create-a-JWT">Create a JWT</h2>



<p>We can consume and test our API using Postman, but the problem here is anyone who knows the endpoint can consume it. So this is not the case, we need an option to control who can consume our service. This is achieved by a JWT bearer token.</p>



<p>Here, we will see how to create a token:</p>



<p><strong>Step 1:</strong> Create an empty API controller called <strong>TokenController</strong>.</p>



<p><strong>Step 2:</strong> Paste the below JWT configuration into the <strong>appsetting.json</strong> file.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="539" height="396" class="wp-image-3409" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Pasting-the-JWT-configuration-into-the-appsetting.json-file.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Pasting-the-JWT-configuration-into-the-appsetting.json-file.png 539w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Pasting-the-JWT-configuration-into-the-appsetting.json-file-300x220.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Pasting-the-JWT-configuration-into-the-appsetting.json-file-50x37.png 50w" sizes="(max-width: 539px) 100vw, 539px" /></figure></div>


<p><strong>Step 3:</strong> Add the action method under <strong>TokenController</strong> to perform the following operations:</p>



<ul>
<li>Accept username and password as input.</li>
<li>Check users’ credentials with database to ensure users’ identity:
<ul>
<li>If valid, access token will be returned.</li>
<li>If invalid, bad request error will be returned.</li>
</ul>
</li>
</ul>



<p>The following code example demonstrates how to create a token.</p>



<pre class="wp-block-code"><code>using InventoryService.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace InventoryService.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class TokenController : ControllerBase
    {
        public IConfiguration _configuration;
        private readonly InventoryContext _context;

        public TokenController(IConfiguration config, InventoryContext context)
        {
            _configuration = config;
            _context = context;
        }

        [HttpPost]
        public async Task&lt;IActionResult&gt; Post(UserInfo _userData)
        {

            if (_userData != null &amp;&amp; _userData.Email != null &amp;&amp; _userData.Password != null)
            {
                var user = await GetUser(_userData.Email, _userData.Password);

                if (user != null)
                {
                    //create claims details based on the user information
                    var claims = new[] {
                    new Claim(JwtRegisteredClaimNames.Sub, _configuration["Jwt:Subject"]),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()),
                    new Claim("Id", user.UserId.ToString()),
                    new Claim("FirstName", user.FirstName),
                    new Claim("LastName", user.LastName),
                    new Claim("UserName", user.UserName),
                    new Claim("Email", user.Email)
                   };

                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));

                    var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                    var token = new JwtSecurityToken(_configuration["Jwt:Issuer"], _configuration["Jwt:Audience"], claims, expires: DateTime.UtcNow.AddDays(1), signingCredentials: signIn);

                    return Ok(new JwtSecurityTokenHandler().WriteToken(token));
                }
                else
                {
                    return BadRequest("Invalid credentials");
                }
            }
            else
            {
                return BadRequest();
            }
        }

        private async Task&lt;UserInfo&gt; GetUser(string email, string password)
        {
            return await _context.UserInfo.FirstOrDefaultAsync(u =&gt; u.Email == email &amp;&amp; u.Password == password);
        }
    }
}</code></pre>



<p>Follow these steps to check the token endpoint using Postman:</p>



<p><strong>Step 1</strong>: Enter this endpoint <a href="https://localhost:44305/api/token" target="_blank" rel="noreferrer noopener">https://localhost:44305/api/token</a>.</p>



<p><strong>Step 2</strong>: Choose the <strong>POST</strong> method and set the header to <strong>‘Content-Type’: ‘application/json’</strong>.</p>



<p><strong>Step 3</strong>: Under Body &gt; Raw, choose type <strong>JSON (application/javascript)</strong> and paste the product details.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="522" height="228" class="wp-image-3410" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application-or-javascript.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application-or-javascript.png 522w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application-or-javascript-300x131.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Choosing-type-JSON-application-or-javascript-50x22.png 50w" sizes="(max-width: 522px) 100vw, 522px" /></figure></div>


<p>By clicking <strong>Send</strong>, user credentials will be checked, and a token will be generated and returned. See the highlighted body section.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="923" height="457" class="wp-image-3411" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Checking-user-credentials-and-generating-a-token.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Checking-user-credentials-and-generating-a-token.png 923w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Checking-user-credentials-and-generating-a-token-300x149.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Checking-user-credentials-and-generating-a-token-768x380.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Checking-user-credentials-and-generating-a-token-50x25.png 50w" sizes="(max-width: 923px) 100vw, 923px" /></figure>



<h2 class="wp-block-heading" id="secure-API-endpoint">Secure API endpoint</h2>



<p>Now, we have a JWT token and will see how to secure our API.</p>



<p><strong>Step 1:</strong> Add the following namespaces to the startup file:</p>



<pre class="wp-block-code"><code>using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;</code></pre>



<p><strong>Step 2:</strong> Configure authorization middleware in the startup <strong>configureService</strong> method.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="995" height="421" class="wp-image-3412" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Configuring-authorization-middleware-in-the-startup-configureService-method.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Configuring-authorization-middleware-in-the-startup-configureService-method.png 995w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Configuring-authorization-middleware-in-the-startup-configureService-method-300x127.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Configuring-authorization-middleware-in-the-startup-configureService-method-768x325.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Configuring-authorization-middleware-in-the-startup-configureService-method-50x21.png 50w" sizes="(max-width: 995px) 100vw, 995px" /></figure>



<p>We have passed the security key used when creating the token, and we have also enabled validation of Issuer and Audience.</p>



<p>Also, we have set <strong>SaveToken </strong>to<strong> true</strong>, which stores the bearer token in <strong>HTTP Context</strong>. So we can access the token in the controller when needed.</p>



<p><strong>Step 3:</strong> Inject the authorization middleware into the Request pipeline.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="531" height="326" class="wp-image-3413" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Injecting-the-authorization-middleware-into-the-Request-pipeline.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Injecting-the-authorization-middleware-into-the-Request-pipeline.png 531w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Injecting-the-authorization-middleware-into-the-Request-pipeline-300x184.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Injecting-the-authorization-middleware-into-the-Request-pipeline-50x31.png 50w" sizes="(max-width: 531px) 100vw, 531px" /></figure></div>


<p><strong>Step 4:</strong> Add authorization attribute to the controller.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="435" height="294" class="wp-image-3414" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Add-authorization-attribute-to-the-controller.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Add-authorization-attribute-to-the-controller.png 435w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Add-authorization-attribute-to-the-controller-300x203.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Add-authorization-attribute-to-the-controller-50x34.png 50w" sizes="(max-width: 435px) 100vw, 435px" /></figure></div>


<p>Here I have added authorization to the whole controller, so all the APIs under this controller will be secured with the token. You can also add authorization to a particular API method.</p>



<p>Follow these steps to test whether the APIs are secured by the JWT:</p>



<p><strong>Step 1:</strong> In Postman, enter this endpoint: https://localhost:44305/api/products.</p>



<p><strong>Step 2:</strong> Choose the <strong>GET</strong> method and then click <strong>Send</strong>. Now, you can see the Status code is <strong>401 Unauthorized.</strong></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="356" class="wp-image-3415" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Status-code-401-Unauthorized-1024x356.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Status-code-401-Unauthorized-1024x356.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Status-code-401-Unauthorized-300x104.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Status-code-401-Unauthorized-768x267.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Status-code-401-Unauthorized-50x17.png 50w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Status-code-401-Unauthorized.png 1127w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>The anonymous access has been blocked and the APIs have been secured. Now, we will see how to access the APIs using the token.</p>



<p><strong>Step 3: </strong>Copy the token that was created in earlier steps.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="177" class="wp-image-3416" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Copying-the-token-created-earlier-1024x177.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Copying-the-token-created-earlier-1024x177.png 1024w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Copying-the-token-created-earlier-300x52.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Copying-the-token-created-earlier-768x133.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Copying-the-token-created-earlier-50x9.png 50w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Copying-the-token-created-earlier.png 1453w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>Step 4: </strong>Prepend text<strong> Bearer </strong>with this token, and finally you will have a token as follows.</p>



<pre class="wp-block-code"><code>Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJJbnZlbnRvcnlTZXJ2aWNlQWNjZXNzVG9rZW4iLCJqdGkiOiIwMGY2MjcwYy05NmFlLTQwMDUtOWUwOS00YWVkMjU5NWNjMTIiLCJpYXQiOiIxMS8yOS8yMDE5IDY6MTc6MDIgQU0iLCJJZCI6IjEiLCJGaXJzdE5hbWUiOiJJbnZlbnRvcnkiLCJMYXN0TmFtZSI6IkFkbWluIiwiVXNlck5hbWUiOiJJbnZlbnRvcnlBZG1pbiIsIkVtYWlsIjoiSW52ZW50b3J5QWRtaW5AYWJjLmNvbSIsImV4cCI6MTU3NTA5NDYyMiwiaXNzIjoiSW52ZW50b3J5QXV0aGVudGljYXRpb25TZXJ2ZXIiLCJhdWQiOiJJbnZldG9yeVNlcnZpY2VQb3N0bWFuQ2xpZW50In0.r3gDqAL9FmH2LA_-nfyLDrihfhuY5ODk1bGOLECaKcI</code></pre>



<p><strong>Step 5:  </strong>Now, come back to the product list. Under the<strong> Authorization </strong>header, paste the previous token in the <strong>Value</strong> field, and then click <strong>Send. </strong>Now you can see the products from our API.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="904" height="690" class="wp-image-3417" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-products-from-our-API.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-products-from-our-API.png 904w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-products-from-our-API-300x229.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-products-from-our-API-768x586.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/The-products-from-our-API-50x38.png 50w" sizes="(max-width: 904px) 100vw, 904px" /></figure>



<ul>
<li>In code-behind, when we pass the authorization header to the API, authentication middleware parses and validates the token. If it is found valid, it will set <strong>UIdentity.IsAuthenticated</strong> to <strong>true</strong>.</li>
<li>The <strong>Authorize</strong> attribute added to the controller will check whether the request is authenticated. If it is true, the API can be accessed.</li>
<li>If <strong>UIdentity.IsAuthenticated</strong> returns false, and a 401 unauthorized error will be returned.</li>
<li>If you need to, you can read <strong>claims</strong> from <strong>Identity</strong>.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="747" height="644" class="wp-image-3418" src="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Quickwatch.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2023/02/Quickwatch.png 747w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Quickwatch-300x259.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Quickwatch-50x43.png 50w, https://topreviewhostingasp.net/wp-content/uploads/2023/02/Quickwatch-240x206.png 240w" sizes="(max-width: 747px) 100vw, 747px" /></figure></div>


<h2 class="wp-block-heading">Conclusion</h2>



<p>In this blog, we have learned how to create a REST API using ASP.NET Core 3.1 and Entity Framework Core to perform basic CRUD operations, create a JWT token, and secure the API. I hope you found this blog useful.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-build-crud-rest-apis-with-asp-net-core-3-1-and-entity-framework/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Scaffold MySQL Database Using Entity Framework</title>
		<link>https://topreviewhostingasp.net/how-to-scaffold-mysql-database-using-entity-framework/</link>
					<comments>https://topreviewhostingasp.net/how-to-scaffold-mysql-database-using-entity-framework/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Wed, 21 Sep 2022 07:32:06 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[entity framework]]></category>
		<category><![CDATA[entity framework tips]]></category>
		<category><![CDATA[entity framework tutorial]]></category>
		<category><![CDATA[mysql database]]></category>
		<category><![CDATA[mysql tips]]></category>
		<category><![CDATA[scaffold entity framework]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3208</guid>

					<description><![CDATA[Sadly, there are a few limitations to using MSSQL as your database engine for your projects. One of them is the fact that your database cannot get bigger than 10 GB. On the bright side, the Entity Framework Core got us covered with MySQL Community alternative! This gives you the ability to connect your project [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Sadly, there are a few limitations to using MSSQL as your database engine for your projects. One of them is the fact that your database cannot get bigger than 10 GB. On the bright side, the Entity Framework Core got us covered with MySQL Community alternative! This gives you the ability to connect your project to a MySQL database while still use the Entity Framework.</p>



<p>In this post I’ll show you how it’s done using the Entity Framework Core Scaffolder in Visual Studio.</p>



<p>What you will need:</p>



<ul>
<li>Visual Studio (most recent version, right now it’s 2019) with .Net Core 2.1 or more recent;</li>
<li><a href="https://dev.mysql.com/downloads/mysql/" target="_blank" rel="noreferrer noopener">MySQL server</a> installed;</li>
<li><a href="https://dev.mysql.com/downloads/workbench/" target="_blank" rel="noreferrer noopener">MySQL Workbench</a> or any other UI to help you create tables and the like. If you feel like a pro, you can also use the command line with MySQL Shell.</li>
</ul>



<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://www.asphostportal.com" target="_blank" rel="noopener"><img loading="lazy" decoding="async" width="300" height="271" class="wp-image-2584 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2018/11/ahp-banner-aspnet-01.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2018/11/ahp-banner-aspnet-01.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2018/11/ahp-banner-aspnet-01-50x45.png 50w" sizes="(max-width: 300px) 100vw, 300px" /></a></figure>
</div>



<h2 class="wp-block-heading">1. Install the Tools!</h2>



<p>Let’s get our environment setup and install all the necessary tools, I’ll stick with MySQL Workbench/MySQL Community combination but you can do as you like. Go to the <a href="https://dev.mysql.com/downloads/windows/installer/8.0.html" target="_blank" rel="noreferrer noopener">download page</a> and download MySQL Community full setup for Windows.</p>



<p>Once it’s installed, you will have to add a new connection to your MySQL Server to be able to connect from Workbench to your server. Here are some sample settings if you’ve installed MySQL to your local machine. Your root password will be asked once you connect to the server.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="626" class="wp-image-3209 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/mysql-workbench-1024x626.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/mysql-workbench-1024x626.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/mysql-workbench-300x183.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/mysql-workbench-768x469.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/mysql-workbench-50x31.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/mysql-workbench.jpg 1347w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">2. Create a Database</h2>



<p>We’ll simply create a test database with two tables joined with a relationship. The classic Classes -&gt; Students example will apply, one class can have many students. Normally we would say that one student can attend many classes but this would complicate the example for no real benefit with a many to many relationship.</p>



<h3 class="wp-block-heading">Database Creation</h3>



<p>Launch MySQL Workbench and create a new Database and give it a name. Then click <strong>Apply</strong> in the bottom right corner.</p>



<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="619" height="275" class="wp-image-3210 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/create-database.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/create-database.jpg 619w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/create-database-300x133.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/create-database-50x22.jpg 50w" sizes="(max-width: 619px) 100vw, 619px" /></figure>
</div>



<p>You might get prompted by the window below, just click <strong>Apply</strong> again to run the SQL statement.</p>



<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="865" height="629" class="wp-image-3211 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/ApplyDatabase.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/ApplyDatabase.jpg 865w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ApplyDatabase-300x218.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ApplyDatabase-768x558.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ApplyDatabase-50x36.jpg 50w" sizes="(max-width: 865px) 100vw, 865px" /></figure>
</div>



<p>The next thing you will want to do is to set the newly created schema (database) as default. That will make sure all the queries we run will apply to this database. Right-click on the schema and click on <strong>Set as detault schema</strong>.</p>



<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="323" height="655" class="wp-image-3212 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/SetAsDefaultSchema.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/SetAsDefaultSchema.jpg 323w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/SetAsDefaultSchema-148x300.jpg 148w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/SetAsDefaultSchema-25x50.jpg 25w" sizes="(max-width: 323px) 100vw, 323px" /></figure>
</div>



<h3 class="wp-block-heading">Create the Tables</h3>



<p>We will now create two tables. Creating a table is very easy with MySQL Workbench! Right-click on the schema and click on <strong>Create table</strong>.</p>



<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="619" height="275" class="wp-image-3213 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/create-database-1.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/create-database-1.jpg 619w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/create-database-1-300x133.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/create-database-1-50x22.jpg 50w" sizes="(max-width: 619px) 100vw, 619px" /></figure>
</div>



<p>Below is the Student table. You might notice that I have put the utf8mb4 charset to conform to the standard UTF8, that will enable us to put special characters in our table. Also, I want to bring your attention on the abbreviations that MySQL seems to expect you to know. Here are the most important ones.</p>



<ul>
<li>PK – Primary Key</li>
<li>NN – Not null (element cannot be left null, good, I hate nulls!)</li>
<li>UQ – Must be unique. By default the primary key is always unique.</li>
<li>AI – Auto incremented column, let’s say 1, 2, 3, 4, … The database engine will automatically keep the count and increment as you add rows.</li>
</ul>



<p>Data types are not exactly the same as in MSSQL but some are similar like <em>VARCHAR</em> and <em>INT</em> which I use in this example for storing strings and numbers respectively.</p>



<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="755" class="wp-image-3214 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentTable-1024x755.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentTable-1024x755.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentTable-300x221.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentTable-768x566.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentTable-50x37.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentTable.jpg 1027w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</div>



<p>And now here is the <strong>Class</strong> table below. For more information, the <em>Level</em> is the year that the student is now in, that is (1, 2, 3, …) depending on your education system.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="761" class="wp-image-3215 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/ClassTable-1024x761.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/ClassTable-1024x761.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ClassTable-300x223.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ClassTable-768x571.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ClassTable-50x37.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ClassTable.jpg 1027w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Once you’ve clicked apply on both tables, it should give you a database just like in this image, but we are still missing the relationship.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="335" height="348" class="wp-image-3216 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/TwoTablesCreated-1.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/TwoTablesCreated-1.jpg 335w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/TwoTablesCreated-1-289x300.jpg 289w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/TwoTablesCreated-1-48x50.jpg 48w" sizes="(max-width: 335px) 100vw, 335px" /></figure>



<h3 class="wp-block-heading">Add the Foreign Key</h3>



<p>We will add the foreign key by going into the table that will contain it, which is Students because <strong>one Class can have MANY Students</strong> but one student can only belong to one class (again for the simplicity of the example).</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1025" height="755" class="wp-image-3217 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentsForeignKey-1.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentsForeignKey-1.jpg 1025w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentsForeignKey-1-300x221.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentsForeignKey-1-768x566.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/StudentsForeignKey-1-50x37.jpg 50w" sizes="(max-width: 1025px) 100vw, 1025px" /></figure>



<p>Give your foreign key a name and select the referenced table in the left panel. Then, in the right panel select the affected column and the referenced column. This will create a reference and an index. Finally, click <strong>Apply</strong> and we’re done!</p>



<h2 class="wp-block-heading">3. Create a New Project in Visual Studio</h2>



<p>Create a new .Net Core 2.1+ project in Visual Studio. Any type will work, <strong>you can also create a .Net Framework project and add the nuget packages to it</strong>.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="466" class="wp-image-3218 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/CreatedProject-1024x466.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/CreatedProject-1024x466.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/CreatedProject-300x137.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/CreatedProject-768x350.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/CreatedProject-1536x699.jpg 1536w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/CreatedProject-50x23.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/CreatedProject.jpg 1814w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">4. Install Required Nuget Packages</h2>



<p><em>Right-click</em> on the target project and click on <strong>Manage Nuget Packages</strong> and head over to <strong>Browse</strong>.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="379" class="wp-image-3219 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/ManageNugetPackages-1024x379.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/ManageNugetPackages-1024x379.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ManageNugetPackages-300x111.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ManageNugetPackages-768x284.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ManageNugetPackages-1536x569.jpg 1536w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ManageNugetPackages-50x19.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ManageNugetPackages.jpg 1883w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">Use the User Interface</h3>



<p>You will need to install two packages :</p>



<ul>
<li>MySql.Data.EntityFrameworkCore.Design</li>
<li>Microsoft.EntityFrameworkCore.Tools</li>
</ul>



<p>Search for them in the <em>Browse</em> tab and click on <em>Install</em>. They will both install many packages required to scaffold and use the Entity Framework Core with MySQL. Simply click <em>ok</em> and <em>accept</em> on the prompts.</p>



<h3 class="wp-block-heading">Or Use the Package Manager Console</h3>



<p><strong>You can also use</strong> the Package Manager Console with the Install-Package commands below.<br /><code><br /><em>Install-Package MySql.Data.EntityFrameworkCore.Design</em><br /><em>Install-Package Microsoft.EntityFrameworkCore.Tools</em></code></p>



<h2 class="wp-block-heading">5. Scaffolding</h2>



<p>Open the Package Manager Console. If you can’t find it, go into <em>View -&gt; Other Windows -&gt; Package Manager Console</em> in the top menu. It should open a panel like the one below.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="328" class="wp-image-3220 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/PackageManagerConsole-1024x328.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/PackageManagerConsole-1024x328.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/PackageManagerConsole-300x96.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/PackageManagerConsole-768x246.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/PackageManagerConsole-50x16.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/PackageManagerConsole.jpg 1531w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>You have to enter the following command in the panel to scaffold your database. You can also create a folder where the created classes will reside.<br /><code><br />Scaffold-DbContext "server=localhost;port=3306;user=root;password=yourpassword;database=test_scaffolding" MySql.Data.EntityFrameworkCore -OutputDir DataAccess\DataObjects -f</code></p>



<p>If you want to specify tables, use the following:<br /><code><br />Scaffold-DbContext "server=localhost;port=3306;user=root;password=yourpassword;database=test_scaffolding" MySql.Data.EntityFrameworkCore -OutputDir DataAccess\DataObjects -Tables class,student -f</code></p>



<p>Also, the <em>-f</em> will force the recreation of the generated classes even if you’ve made changes, so be careful! Make sure that the right project is selected before running commands in the Package Manager Console or you will affect another project (red rectangle in the image below).</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="173" class="wp-image-3221 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/Scaffolding-1-1024x173.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/Scaffolding-1-1024x173.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/Scaffolding-1-300x51.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/Scaffolding-1-768x130.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/Scaffolding-1-1536x259.jpg 1536w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/Scaffolding-1-50x8.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/Scaffolding-1.jpg 1877w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>As you can see, the first run went well and created the classes as intended, but when I tried to re-run the command on a specific table, I needed to add the <em>-f</em> force argument to overwrite.</p>



<h3 class="wp-block-heading">Use the Created Context</h3>



<p>Once the context has been created with the command above, you will get one class per table plus one Context that you’ll use to access the data.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="410" class="wp-image-3222 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/ContextCreated-1-1024x410.jpg" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/ContextCreated-1-1024x410.jpg 1024w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ContextCreated-1-300x120.jpg 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ContextCreated-1-768x307.jpg 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ContextCreated-1-1536x615.jpg 1536w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ContextCreated-1-50x20.jpg 50w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/ContextCreated-1.jpg 1891w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Now it’s time to head to Program.cs in our console application and call the DataContext.</p>



<pre class="wp-block-code"><code>using System;
using System.Linq;
 
using ScaffoldingWithMySQL.DataAccess.DataObjects;
 
namespace ScaffoldingWithMySQL
{
    class Program
    {
        static void Main(string[] args)
        {
            test_scaffoldingContext dataContext = new test_scaffoldingContext();
             
            //Create a new student object to add to the class
            Student newStudent = new Student()
            {
                CardNumber = "TEST329812",
                Level = 1,
                FirstName = "Simon",
                LastName = "Test"
            };
             
            //Create a new class object
            Class newClass = new Class()
            {
                Department = "English",
                Level = 1,
                Title = "English Class",
                Year = 2019
            };
 
            //Let's add a student to the class and then add the class to the classes in the database.
            newClass.Student.Add(newStudent);  
            dataContext.Class.Add(newClass);
 
            //Don't forget to save changes!
            dataContext.SaveChanges();
        }
    }
}</code></pre>



<p>The above code is an example of how you can use your newly create DataContext to access your data. If you want more information about the process of Scaffolding with MySQL, you can go on the <a href="https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core-scaffold-example.html" target="_blank" rel="noreferrer noopener">MySQL Website</a>. I hope this post will be useful for a few of you!</p>



<h2 class="wp-block-heading">Having Some Errors or Issues?</h2>



<p>I found recently that using different versions of NuGet packages can lead to strange behaviours from the MySQL scaffold engine. What I would recommend is that you have a look at <a href="https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core.html#connector-net-entityframework-core-versions" target="_blank" rel="noreferrer noopener">this link from the MySQL Website</a> which gives you the version compatibility. Make sure the <strong>Microsoft.EntityFrameworkCore</strong> and <strong>MySQL.Data.EntityFrameworkCore</strong> versions are correct according to the previous documentation.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="783" height="637" class="wp-image-3223 aligncenter" src="https://topreviewhostingasp.net/wp-content/uploads/2022/09/EFCoreMySQLScaffoldVersion.png" alt="" srcset="https://topreviewhostingasp.net/wp-content/uploads/2022/09/EFCoreMySQLScaffoldVersion.png 783w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/EFCoreMySQLScaffoldVersion-300x244.png 300w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/EFCoreMySQLScaffoldVersion-768x625.png 768w, https://topreviewhostingasp.net/wp-content/uploads/2022/09/EFCoreMySQLScaffoldVersion-50x41.png 50w" sizes="(max-width: 783px) 100vw, 783px" /></figure>



<h2 class="wp-block-heading">Conclusion</h2>



<p>Done! You have learned how to scaffold your MySQL database with Entity Framework. If you found this article helpful, please feel free to share it. Thank you</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-scaffold-mysql-database-using-entity-framework/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Use Entity Framework Connect to SQL Server</title>
		<link>https://topreviewhostingasp.net/how-to-use-entity-framework-connect-to-sql-server/</link>
					<comments>https://topreviewhostingasp.net/how-to-use-entity-framework-connect-to-sql-server/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Fri, 18 Mar 2022 07:44:06 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[.net core 6]]></category>
		<category><![CDATA[asp net core 6 tips]]></category>
		<category><![CDATA[asp net core 6 tutorial]]></category>
		<category><![CDATA[entity framework tips]]></category>
		<category><![CDATA[entity framework tutorial]]></category>
		<category><![CDATA[sql server]]></category>
		<category><![CDATA[sql tutorial]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=3013</guid>

					<description><![CDATA[This post shows goes through the steps to connect a .NET 6 API to SQL Server using Entity Framework Core, and automatically create/update the SQL Server database from code using EF Core migrations. We&#8217;ll start with an example .NET 6 CRUD API from a tutorial I posted recently, it uses the EF Core InMemory db [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>This post shows goes through the steps to connect a .NET 6 API to SQL Server using Entity Framework Core, and automatically create/update the SQL Server database from code using EF Core migrations.</p>



<p>We&#8217;ll start with an example .NET 6 CRUD API from a tutorial I posted recently, it uses the EF Core InMemory db provider by default for testing, we&#8217;ll update it to connect to a SQL Server database and run EF Core migrations to auto generate the database and tables from code. </p>



<h2 class="wp-block-heading">Requirements!</h2>



<p>To follow the steps in this tutorial you&#8217;ll need the following:</p>



<ul>
<li><a href="https://dotnet.microsoft.com/download" target="_blank" rel="noreferrer noopener">.NET SDK</a> &#8211; includes the .NET runtime and command line tools.</li>
<li><a href="https://code.visualstudio.com/" target="_blank" rel="noreferrer noopener">Visual Studio Code</a> &#8211; code editor that runs on Windows, Mac and Linux. If you have a different preferred code editor that&#8217;s fine too.</li>
<li><a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp" target="_blank" rel="noreferrer noopener">C# extension</a> for Visual Studio Code &#8211; adds support to VS Code for developing .NET applications.</li>
<li>SQL Server &#8211; you&#8217;ll need access to running SQL Server instance for the API to connect to, it can be remote (e.g. Azure, AWS etc) or on your local machine. The Express edition of SQL Server is available for free at <a href="https://www.microsoft.com/sql-server/sql-server-downloads" target="_blank" rel="noreferrer noopener">https://www.microsoft.com/sql-server/sql-server-downloads</a>.</li>
</ul>



<h2 class="wp-block-heading">Download &amp; Run the example .NET 6 API</h2>



<p>Follow these steps to download and run the .NET 6 CRUD API on your local machine with the default EF Core InMemory database:</p>



<ol>
<li>Download or clone the tutorial project code from <a href="https://github.com/cornflourblue/dotnet-6-crud-api" target="_blank" rel="noreferrer noopener">https://github.com/cornflourblue/dotnet-6-crud-api</a></li>
<li>Start the api by running <code>dotnet run</code> from the command line in the project root folder (where the WebApi.csproj file is located), you should see the message <code>Now listening on: http://localhost:4000</code>.</li>
<li>You can test the API directly with a tool such as <a href="https://www.postman.com/downloads" target="_blank" rel="noreferrer noopener">Postman</a>.</li>
</ol>



<h4 class="wp-block-heading">Starting in debug mode</h4>



<p>You can also start the application in debug mode in VS Code by opening the project root folder in VS Code and pressing F5 or by selecting Debug -&gt; Start Debugging from the top menu, running in debug mode allows you to attach breakpoints to pause execution and step through the application code.</p>



<h2 class="wp-block-heading">Update .NET 6 API to use SQL Server</h2>



<h4 class="wp-block-heading"><br />Add SQL Server database provider from NuGet</h4>



<p>Run the following command from the project root folder to install the EF Core database provider for SQL Server from NuGet:</p>



<pre class="wp-block-code"><code>dotnet add package Microsoft.EntityFrameworkCore.SqlServer</code></pre>



<h4 class="wp-block-heading">Add connection string to app settings</h4>



<p>Open the <code>appsettings.json</code> file and add the entry <code>"ConnectionStrings"</code> with a child entry for the SQL Server connection string (e.g. <code>"WebApiDatabase"</code>), the connection string should be in the format <code>"Data Source=[DB SERVER URL]; Initial Catalog=[DB NAME]; User Id=[USERNAME]; Password=[PASSWORD]"</code>, or to connect with the same account that is running the .NET API use the connection string format <code>"Data Source=[DB SERVER URL]; Initial Catalog=[DB NAME]; Integrated Security=true"</code>.</p>



<p>When EF Core migrations generates the database, the <code>Initial Catalog</code> value will be the name of the database created in SQL Server.</p>



<p>The updated <code>appsettings.json</code> file with the connection string should look something like this:</p>



<pre class="wp-block-code"><code>{
    "ConnectionStrings": {
        "WebApiDatabase": "Data Source=localhost; Initial Catalog=dotnet-6-crud-api; User Id=testUser; Password=testPass123"
    },
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft.AspNetCore": "Warning"
        }
    }
}</code></pre>



<h4 class="wp-block-heading">Update Data Context to Use SQL Server</h4>



<p>The <code>DataContext</code> class located at <code>/Helpers/DataContext.cs</code> is used for accessing application data through Entity Framework. It derives from the Entity Framework <code>DbContext</code> class and has a public <code>Users</code> property for accessing and managing user data.</p>



<p>Update the <code>OnConfiguring()</code> method to connect to SQL Server instead of an in memory database by replacing <code>options.UseInMemoryDatabase("TestDb");</code> with <code>options.UseSqlServer(Configuration.GetConnectionString("WebApiDatabase"));</code>.</p>



<p>The updated <code>DataContext</code> class should look like this:</p>



<pre class="wp-block-code"><code>namespace WebApi.Helpers;

using Microsoft.EntityFrameworkCore;
using WebApi.Entities;

public class DataContext : DbContext
{
    protected readonly IConfiguration Configuration;

    public DataContext(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        // connect to sql server with connection string from app settings
        options.UseSqlServer(Configuration.GetConnectionString("WebApiDatabase"));
    }

    public DbSet&lt;User&gt; Users { get; set; }
}</code></pre>



<h2 class="wp-block-heading">Create SQL Database from code with EF Core Migrations</h2>



<h4 class="wp-block-heading"><br />Install dotnet ef tools</h4>



<p>The .NET Entity Framework Core tools (<code>dotnet ef</code>) are used to generate EF Core migrations, to install the EF Core tools globally run <code>dotnet tool install -g dotnet-ef</code>, or to update run <code>dotnet tool update -g dotnet-ef</code>. For more info on EF Core tools see <a href="https://docs.microsoft.com/ef/core/cli/dotnet" target="_blank" rel="noreferrer noopener">https://docs.microsoft.com/ef/core/cli/dotnet</a></p>



<h4 class="wp-block-heading">Add EF Core Design package from NuGet</h4>



<p>Run the following command from the project root folder to install the EF Core design package, it provides cross-platform command line tooling support and is used to generate EF Core migrations:</p>



<pre class="wp-block-code"><code>dotnet add package Microsoft.EntityFrameworkCore.Design</code></pre>



<h4 class="wp-block-heading">Generate EF Core migrations</h4>



<p>Generate new EF Core migration files by running the command <code>dotnet ef migrations add InitialCreate</code> from the project root folder (where the WebApi.csproj file is located), these migrations will create the database and tables for the .NET Core API.</p>



<h4 class="wp-block-heading">Execute EF Core migrations</h4>



<p>Run the command <code>dotnet ef database update</code> from the project root folder to execute the EF Core migrations and create the database and tables in SQL Server.</p>



<p>Check SQL Server and you should now see your database with the tables <code>Users</code> and <code>__EFMigrationsHistory</code>.</p>



<h2 class="wp-block-heading">Restart .NET 6.0 CRUD API</h2>



<p>Stop and restart the API with the command <code>dotnet run</code> from the project root folder, you should see the message <code>Now listening on: http://localhost:4000</code> and the API should now be connected to SQL Server.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-use-entity-framework-connect-to-sql-server/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>How to Create Entity Core Migrations for SQLite and SQL Server</title>
		<link>https://topreviewhostingasp.net/how-to-create-entity-core-migrations-for-sqlite-and-sql-server/</link>
					<comments>https://topreviewhostingasp.net/how-to-create-entity-core-migrations-for-sqlite-and-sql-server/#respond</comments>
		
		<dc:creator><![CDATA[Jacques Hunt]]></dc:creator>
		<pubDate>Fri, 28 May 2021 07:55:45 +0000</pubDate>
				<category><![CDATA[Hosting Tips]]></category>
		<category><![CDATA[entity framework]]></category>
		<category><![CDATA[entity framework database migration]]></category>
		<category><![CDATA[entity framework migration]]></category>
		<category><![CDATA[entity framework tips]]></category>
		<category><![CDATA[entity framework tutorial]]></category>
		<category><![CDATA[sql server]]></category>
		<category><![CDATA[sqlite]]></category>
		<guid isPermaLink="false">https://topreviewhostingasp.net/?p=2965</guid>

					<description><![CDATA[In this post we&#8217;ll go through an example of how to setup an ASP.NET Core project with EF Core DB Contexts and Migrations that support multiple different database providers. The below steps show how to use a SQLite database in development and a SQL Server database in production, but you could switch these to any [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In this post we&#8217;ll go through an example of how to setup an ASP.NET Core project with EF Core DB Contexts and Migrations that support multiple different database providers.</p>



<p>The below steps show how to use a SQLite database in development and a SQL Server database in production, but you could switch these to any database providers you like that are supported by EF Core.</p>



<h2 class="wp-block-heading">Create Main EF Core DB Context for SQL Server</h2>



<p>Create the main DB context class that defines the entities available in the database via <code>public DbSet&lt;TEntity&gt;</code> properties, and configure it to connect to the production database (SQL Server in this case).</p>



<p>Below is the main DB context from the example ASP.NET Core api linked above, it has the class name <code>DataContext</code> and is located in the <code>/Helpers</code> directory of the project, but you can choose any class name and directory you prefer.</p>



<pre class="wp-block-code"><code>using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using WebApi.Entities;

namespace WebApi.Helpers
{
    public class DataContext : DbContext
    {
        protected readonly IConfiguration Configuration;

        public DataContext(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            // connect to sql server database
            options.UseSqlServer(Configuration.GetConnectionString("WebApiDatabase"));
        }

        public DbSet&lt;User&gt; Users { get; set; }
    }
}</code></pre>



<h2 class="wp-block-heading">Create Development EF Core DB Context for SQLite</h2>



<p>Create a development DB context that inherits from the main DB context above and overrides the database provider in the <code>OnConfiguring()</code> method.</p>



<p>Below is the development DB context from the example ASP.NET Core api that overrides the database provider to connect to SQLite instead of SQL Server. Having a second EF Core DB Context that derives from the main DB context is what enables the project to support multiple different database providers.</p>



<pre class="wp-block-code"><code>using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

namespace WebApi.Helpers
{
    public class SqliteDataContext : DataContext
    {
        public SqliteDataContext(IConfiguration configuration) : base(configuration) { }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            // connect to sqlite database
            options.UseSqlite(Configuration.GetConnectionString("WebApiDatabase"));
        }
    }
}</code></pre>



<h2 class="wp-block-heading">Generate SQLite EF Core Migrations</h2>



<p>Run the following command to generate EF Core migrations for SQLite and store them in their own folder.</p>



<pre class="wp-block-code"><code>dotnet ef migrations add InitialCreate --context SqliteDataContext --output-dir Migrations/SqliteMigrations
</code></pre>



<h2 class="wp-block-heading">Generate SQL Server EF Core Migrations</h2>



<p>Run the following command to generate EF Core migrations for SQL Server and store them in their own folder.</p>



<p>The environment variable <code>ASPNETCORE_ENVIRONMENT</code> needs to be set to <code>Production</code> so the SQL Server <code>DataContext</code> class is configured with the .NET Core dependency injection system, see the <code>ConfigureServices()</code> method below.</p>



<p>Configuring environment variables from the command line is slightly different on MacOS and Windows.</p>



<p><strong>Windows</strong></p>



<pre class="wp-block-code"><code>set ASPNETCORE_ENVIRONMENT=Production
dotnet ef migrations add InitialCreate --context DataContext --output-dir Migrations/SqlServerMigrations</code></pre>



<p><strong>MacOS</strong></p>



<pre class="wp-block-code"><code>ASPNETCORE_ENVIRONMENT=Production dotnet ef migrations add InitialCreate --context DataContext --output-dir Migrations/SqlServerMigrations
</code></pre>



<h2 class="wp-block-heading">Configure Startup.cs to use SQLite in Development and SQL Server in Production</h2>



<p>Below is a cut down version of the Startup.cs file from the example ASP.NET Core api that just includes the bits related to the EF Core DB context configuration and automatic database migration.</p>



<p>Lines <code>23 - 26</code> configure which type of data context is injected by the .NET Core dependency injection system when a <code>DataContext</code> instance is required by a class. In production an instance of the main <code>DataContext</code> class is used which connects to SQL Server, otherwise (i.e. in development) an instance of the <code>SqliteDataContext</code> is used.</p>



<p>An instance of the <code>DataContext</code> is injected as a parameter into the <code>Configure()</code> method, the data context instance is then used to apply any pending migrations to the database by calling the <code>dataContext.Database.Migrate()</code> method on line <code>35</code>.</p>



<pre class="wp-block-code"><code>using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using WebApi.Helpers;

namespace WebApi
{
    public class Startup
    {
        private readonly IWebHostEnvironment _env;

        public Startup(IWebHostEnvironment env)
        {
            _env = env;
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // use sql server db in production and sqlite db in development
            if (_env.IsProduction())
                services.AddDbContext&lt;DataContext&gt;();
            else
                services.AddDbContext&lt;DataContext, SqliteDataContext&gt;();

            ...
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext)
        {
            // migrate any database changes on startup (includes initial db creation)
            dataContext.Database.Migrate();
            
            ...
        }
    }
}</code></pre>



<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://topreviewhostingasp.net/how-to-create-entity-core-migrations-for-sqlite-and-sql-server/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
