介绍 (Introduction)
In this article, we are going to create a cascading dropdown list in Blazor using Entity Framework Core database first approach. We will create two dropdown lists — Country and City. Upon selecting the value from the country dropdown, we will change the value of the City dropdown.
在本文中,我们将使用Entity Framework Core数据库优先方法在Blazor中创建级联下拉列表。 我们将创建两个下拉列表-Country和City 。 从国家下拉列表中选择值后,我们将更改城市下拉列表的值。
We will be using Visual Studio 2017 and SQL Server 2014.
我们将使用Visual Studio 2017和SQL Server 2014。
Let’s take a look at the final product.
让我们看一下最终产品。
先决条件 (Prerequisites)
Install .NET Core 2.1 Preview 2 SDK from here
从此处安装.NET Core 2.1 Preview 2 SDK
Install Visual Studio 2017 v15.7 or above from here
从此处安装Visual Studio 2017 v15.7或更高版本
Install ASP.NET Core Blazor Language Services extension from here
从此处安装ASP.NET Core Blazor语言服务扩展
- SQL Server 2008 or above SQL Server 2008或以上
Blazor framework is not supported by versions below Visual Studio 2017 v15.7.
Visual Studio 2017 v15.7以下的版本不支持Blazor框架。
源代码 (Source Code)
Before proceeding, I would recommend that you get the source code from GitHub.
在继续之前,我建议您从GitHub获取源代码。
建立表格 (Creating Tables)
We will be using two tables to store our data.
我们将使用两个表来存储我们的数据。
- Country: used to store the name of the Country. It contains two fields — CountryId and CountryName. 国家/地区:用于存储国家/地区的名称。 它包含两个字段-CountryId和CountryName。
- Cities: This contains the list of cities for the Countries we will insert in the Country table. It contains three fields — CityId, CountryId, and CityName. The CountryId column is a foreign key referring to CountryId in the Country table. 城市:这包含我们要在“国家/地区”表中插入的国家/地区的城市列表。 它包含三个字段-CityId,CountryId和CityName。 CountryId列是一个外键,表示Country表中的CountryId。
Execute the following commands to create both tables:
执行以下命令来创建两个表:
CREATE TABLE Country(CountryId VARCHAR(5) PRIMARY KEY,CountryName VARCHAR(20) NOT NULL)GOCREATE TABLE Cities(CityId VARCHAR(5) PRIMARY KEY,CountryId VARCHAR(5) FOREIGN KEY REFERENCES Country(CountryId),CityName VARCHAR(20) NOT NULL)GO
Now we will put some data in both of the tables. Open the Country table and execute the following insert statement.
现在,我们将一些数据放入两个表中。 打开国家表并执行以下插入语句。
INSERT INTO Country VALUES ('C1', 'India')INSERT INTO Country VALUES ('C2', 'China')INSERT INTO Country VALUES ('C3', 'USA')
Then execute the following insert statements to insert data into the Cities table.
然后执行以下插入语句,将数据插入到“城市”表中。
INSERT INTO Cities VALUES ('P1','C1','New Delhi')INSERT INTO Cities VALUES ('P2','C1','Mumbai')INSERT INTO Cities VALUES ('P3','C1','Chennai')INSERT INTO Cities VALUES ('P4','C1','Hyderabad')INSERT INTO Cities VALUES ('P5','C1','Bengaluru')INSERT INTO Cities VALUES ('P6','C2','Beijing')INSERT INTO Cities VALUES ('P7','C2','Shanghai')INSERT INTO Cities VALUES ('P8','C2','Hong Kong')INSERT INTO Cities VALUES ('P9','C2','Macau')INSERT INTO Cities VALUES ('P10','C3','New York')INSERT INTO Cities VALUES ('P11','C3','Chicago')INSERT INTO Cities VALUES ('P12','C3','Las Vegas')
创建Blazor Web应用程序 (Create Blazor Web Application)
Open Visual Studio and select File >> New >> Project.
打开Visual Studio,然后选择“文件>>新建>>项目”。
After selecting the project, a “New Project” dialog will open. Select .NET Core inside the Visual C# menu from the left panel. Then, select “ASP.NET Core Web Application” from the available project types. Name the project “BlazorDDL” and press OK.
选择项目后,将打开“新建项目”对话框。 从左侧面板的Visual C#菜单中选择.NET Core。 然后,从可用的项目类型中选择“ ASP.NET Core Web应用程序”。 将项目命名为“ BlazorDDL” 然后按确定。
After clicking on OK, a new dialog will open asking you to select the project template. You can see two drop-down menus at the top left of the template window. Select “.NET Core” and “ASP.NET Core 2.0” from these dropdowns. Then, select the “Blazor (ASP .NET Core hosted)” template and press OK.
单击确定后,将打开一个新对话框,要求您选择项目模板。 您可以在模板窗口的左上方看到两个下拉菜单。 从这些下拉列表中选择“ .NET Core”和“ ASP.NET Core 2.0”。 然后,选择“ Blazor(ASP.NET Core托管)”模板,然后按OK。
Now, our Blazor solution will be created. You can see the folder structure in Solution Explorer as shown in the below image.
现在,将创建我们的Blazor解决方案。 您可以在解决方案资源管理器中看到文件夹结构,如下图所示。
You can see that we have three project files created inside this solution.
您可以看到我们在此解决方案内部创建了三个项目文件。
- BlazorDDL.Client: it has the client side code and contains the pages that will be rendered on the browser. BlazorDDL.Client:它具有客户端代码,并包含将在浏览器中呈现的页面。
- BlazorDDL.Server: it has the server side code, such as DB related operations and web API. BlazorDDL.Server:它具有服务器端代码,例如与DB相关的操作和Web API。
- BlazorDDL.Shared: it contains the shared code that can be accessed by both client and server. BlazorDDL.Shared:它包含可以由客户端和服务器访问的共享代码。
搭建应用模型 (Scaffolding the Model to the Application)
We are using Entity Framework core database first approach to create our models. We will create our model class in the “BlazorDDL.Shared” project so that it can be accessible to both the client and server project.
我们正在使用Entity Framework核心数据库优先方法来创建模型。 我们将在“ BlazorDDL.Shared”项目中创建模型类,以便客户端和服务器项目都可以访问它。
Navigate to Tools >> NuGet Package Manager >> Package Manager Console. Select “BlazorDDL.Shared” from the Default project dropdown. Refer to the image below:
导航到工具>> NuGet软件包管理器>>软件包管理器控制台。 从默认项目下拉菜单中选择“ BlazorDDL.Shared”。 请参考下图:
First we will install the package for the database provider that we are targeting, which is SQL Server in this case. Run the following command:
首先,我们将为目标数据库安装程序安装软件包,在本例中为SQL Server。 运行以下命令:
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Since we are using Entity Framework Tools to create a model from the existing database, we will install the tools package as well. Run the following command:
由于我们使用实体框架工具从现有数据库创建模型,因此我们还将安装工具包。 运行以下命令:
Install-Package Microsoft.EntityFrameworkCore.Tools
After you have installed both packages, we will scaffold our model from the database tables using the following command:
安装完两个软件包之后,我们将使用以下命令从数据库表中构建模型:
Scaffold-DbContext "Your connection string here" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables Country, Cities
Do not forget to put your own connection string (inside “ ”). After this command gets executed successfully, you can see that a Models folder has been created and contains three class files: “myTestDBContext.cs”, “Cities.cs”, and “Country.cs”. And so we have successfully scaffolded our Models using EF core database first approach.
不要忘记在“”中放入自己的连接字符串。 成功执行此命令后,可以看到已经创建了一个Models文件夹,其中包含三个类文件:“ myTestDBContext.cs”, “ Cities.cs”和“ Country.cs”。 因此,我们已经成功使用EF核心数据库优先方法建立了模型。
At this point in time, the Models folder will have the following structure.
此时,“模型”文件夹将具有以下结构。
为应用程序创建数据访问层 (Creating the Data Access Layer for the Application)
Right click on “BlazorDDL.Server” project and then select Add >> New Folder and name the folder “DataAccess”. We will be adding our class to handle database-related operations inside this folder only.
右键单击“ BlazorDDL.Server”项目,然后选择“添加>>新建文件夹”,并将文件夹命名为“ DataAccess”。 我们将添加我们的类,以仅在此文件夹内处理与数据库相关的操作。
Right click on the “DataAccess” folder and select Add >> Class. Name your class “DataAccessClass.cs”. This class will handle our database-related operations.
右键单击“ DataAccess”文件夹,然后选择“添加>>类”。 将您的类命名为“ DataAccessCl ass .cs”。 此类将处理与数据库有关的操作。
Open “DataAccessLayer.cs” and put the following code into it.
打开“ DataAccessLayer.cs” 并将以下代码放入其中。
using BlazorDDL.Shared.Models;using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;namespace BlazorDDL.Server.DataAcces{ public class DataAccessLayer { myTestDBContext db = new myTestDBContext(); public IEnumerable<Country> GetAllCountries() { try { return db.Country.ToList(); } catch { throw; } } public IEnumerable<Cities> GetCityData(string id) { try { List<Cities> lstCity = new List<Cities>(); lstCity = (from CityName in db.Cities where CityName.CountryId == id select CityName).ToList(); return lstCity; } catch { throw; } } }}
Here we have defined two methods:
这里我们定义了两种方法:
- GetAllCountries: it will fetch all the country data from the country table. GetAllCountries:它将从国家表中获取所有国家数据。
- GetCityData: it will fetch the city data corresponding to the country id provided to it. GetCityData:它将获取与提供给它的国家/地区ID相对应的城市数据。
Now our data access layer is complete. We will proceed to create our web API Controller.
现在我们的数据访问层已经完成。 我们将继续创建Web API控制器。
将Web API控制器添加到应用程序 (Adding the web API Controller to the Application)
Right click on the “BlazorDDL.Server/Controllers” folder and select Add >> New Item. An “Add New Item” dialog box will open. Select “ASP.NET” from the left panel, then select “API Controller Class” from templates panel and name it “CountriesController.cs”. Press Add.
右键单击“ BlazorDDL.Server / Controllers”文件夹,然后选择添加>>新建项。 “添加新项”对话框将打开。 从左侧面板中选择“ ASP.NET”,然后从模板面板中选择“ API Controller Class”,并将其命名为“ CountriesController.cs”。 按添加。
This will create our API “CountriesController” class.
这将创建我们的API“ CountriesController”类。
We will call the methods of the “DataAccessLayer” class to fetch data and pass on the data to the client side.
我们将调用“ DataAccessLayer”类的方法来获取数据并将数据传递给客户端。
Open the “CountriesController.cs” file and put the following code into it.
打开“ CountriesController.cs” 文件,并将以下代码放入其中。
using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using BlazorDDL.Server.DataAcces;using BlazorDDL.Shared.Models;using Microsoft.AspNetCore.Mvc;using Microsoft.AspNetCore.Http;namespace BlazorDDL.Server.Controllers{ public class CountriesController : Controller { DataAccessLayer objCountry= new DataAccessLayer(); [HttpGet] [Route("api/Countries/GetCountryList")] public IEnumerable<Country> GetCountryList() { return objCountry.GetAllCountries(); } [HttpGet] [Route("api/Countries/GetCities/{id}")] public IEnumerable<Cities> GetCities(string id) { return objCountry.GetCityData(id); } }}
At this point in time, our BlazorDDL.Server project has the following structure.
此时,我们的BlazorDDL.Server项目具有以下结构。
We are done with our backend logic. Therefore, we will now proceed to code our client side.
我们已经完成了后端逻辑。 因此,我们现在开始对客户端进行编码。
将Razor视图添加到应用程序 (Adding Razor View to the Application)
Right click on the “BlazorDDL.Client/Page”s folder and then select Add >> New Item. An “Add New Item” dialog box will open. Select Web from the left panel, then select “Razor View” from the templates panel and name it “CountryData.cshtml”.
右键单击“ BlazorDDL.Client / Page” 的文件夹,然后选择添加>>新建项目。 “添加新项”对话框将打开。 从左侧面板中选择Web,然后从模板面板中选择“ Razor View”,并将其命名为“ CountryData.c s html”。
This will add a “CountryData.cshtml” page to our “BlazorDDL.Client/Pages” folder.
这将添加一个“ CountryData.cshtml” 页面到“ BlazorDDL.Client / Pages”文件夹。
Open the “CountryData.cshtml” page and put the following code into it.
打开“ CountryData.cshtml” 页面并将以下代码放入其中。
@using BlazorDDL.Shared.Models@page "/country"@inject HttpClient Http<h1>Country Data</h1><p>This component demonstrates cascading dropdownlist using EntityFrameWork Core</p><hr />@if (countryList == null){ <p><em>Loading...</em></p>}else{ <div class="row"> <div class="col-md-4"> <label for="Country" class="control-label">Country</label> </div> <div class="col-md-4"> <label asp-for="Cities" class="control-label">Cities</label> </div> </div> <div class="row" style="padding-top:10px"> <div class="col-md-4"> <select class="form-control" onchange="@CountryClicked"> <option value="">-- Select Country --</option> @foreach (var country in countryList) { <option value="@country.CountryId">@country.CountryName</option> } </select> </div> <div class="col-md-4"> <select class="form-control" onchange="@CityClicked"> <option value="">-- Select City --</option> @if (cityList != null) { @foreach (var city in cityList) { <option value="@city.CityName">@city.CityName</option> } } </select> </div> </div> <div class="row" style="padding-top:50px"> <div class="col-md-4"> <label class="control-label">Country Name: @countryName</label> </div> <div class="col-md-4"> <label class="control-label">City Name: @cityName</label> </div> </div>}@functions {List<Country> countryList = new List<Country>();List<Cities> cityList = new List<Cities>();string countryId { get; set; }string countryName { get; set; }string cityName { get; set; }protected override async Task OnInitAsync(){ countryList = await Http.GetJsonAsync<List<Country>>("api/Countries/GetCountryList");}protected async void CountryClicked(UIChangeEventArgs countryEvent){ cityList.Clear(); cityName = string.Empty; countryId = countryEvent.Value.ToString(); countryName = countryList.FirstOrDefault(s => s.CountryId == countryId).CountryName; cityList = await Http.GetJsonAsync<List<Cities>>("api/Countries/GetCities/" + countryId); this.StateHasChanged();}void CityClicked(UIChangeEventArgs cityEvent){ cityName = cityEvent.Value.ToString(); this.StateHasChanged();}}
Let’s understand this code.
让我们了解这段代码。
At the top, we have included BlazorDDL.Shared.Models namespace so that we can use our Country and Cities model class on this page. We define the route of this page using the @page directive. So, in this application, if we append “/country” to the base URL, then we will be redirected to this page. We are also injecting HttpClient service to enable the web API call.
在顶部,我们包括BlazorDDL.Shared.Models命名空间,以便我们可以在此页面上使用Country和Cities模型类。 我们使用@page指令定义此页面的路由。 因此,在此应用程序中,如果我们在基本URL后面附加“ / country”,那么我们将被重定向到此页面。 我们还将注入HttpClient服务以启用Web API调用。
Then we have defined the HTML section to display two Dropdown lists on our web page. We are calling the “CountryClicked” method on the “onchange” event of the Country dropdown. This method will call the “GetCites” web API method to fetch the city data from the Cities table corresponding to the countryid of the selected country.
然后,我们定义了HTML部分,以在我们的网页上显示两个下拉列表。 我们在“国家/地区”下拉列表的“ onchange”事件中调用“ CountryClicked”方法。 此方法将调用“ GetCites” Web API方法,以从“城市”表中获取与所选国家/地区的国家/地区对应的城市数据。
We are also setting the value of the “countryName” property to the selected country. The “StateHasChanged” method is invoked to refresh the UI. This will ensure that the City dropdown list will get refreshed on changing the country dropdown.
我们还将“ countryName”属性的值设置为所选国家。 调用“ StateHasChanged”方法以刷新UI。 这将确保在更改国家/地区下拉列表时刷新城市下拉列表。
Similarly, we have another dropdown list to display cities data corresponding to each country. On the “onchange” event of the Cities dropdown, we are setting the value of the “cityName” property to the selected city.
同样,我们还有另一个下拉列表来显示每个国家/地区对应的城市数据。 在“城市”下拉列表的“ onchange”事件中,我们将“ cityName”属性的值设置为所选城市。
We are also displaying the selected country name and city name value on the webpage.
我们还在网页上显示所选的国家名称和城市名称值。
The @functions section contains all our properties and methods. We have defined two variables: countryList of type Country, and cityList of type City. These handle the countries and cities data, respectively. We have also declared three properties to handle the countryId, countryName, and cityName data.
@functions部分包含我们所有的属性和方法。 我们定义了两个变量:Country类型的countryList和City类型的cityList。 这些分别处理国家和城市数据。 我们还声明了三个属性来处理countryId,countryName和cityName数据。
Inside the “OnInitAsync” method, we are calling the GetCountryList web API method to populate countryList. This variable is used to bind the data to the Country dropdown list on page load.
在“ OnInitAsync”方法内部,我们正在调用GetCountryList Web API方法来填充countryList。 此变量用于在页面加载时将数据绑定到“国家/地区”下拉列表。
将链接添加到导航菜单 (Adding the Link to the Navigation menu)
The last step is to add the link to our “CountryData” page in the navigation menu. Open the “BlazorDDL.Client/Shared/NavMenu.cshtml” page and put the following code into it.
最后一步是将链接添加到导航菜单中的“ CountryData”页面。 打开“ BlazorDDL.Client / Shared / NavMenu.cshtml”页面,并将以下代码放入其中。
<div class="top-row pl-4 navbar navbar-dark"> <a class="navbar-brand" href="/">BlazorDDL</a> <button class="navbar-toggler" onclick=@ToggleNavMenu> <span class="navbar-toggler-icon"></span> </button></div><div class=@(collapseNavMenu ? "collapse" : null) onclick=@ToggleNavMenu> <ul class="nav flex-column"> <li class="nav-item px-3"> <NavLink class="nav-link" href="/" Match=NavLinkMatch.All> <span class="oi oi-home" aria-hidden="true"></span> Home </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="/counter"> <span class="oi oi-plus" aria-hidden="true"></span> Counter </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="/fetchdata"> <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data </NavLink> </li> <li class="nav-item px-3"> <NavLink class="nav-link" href="/country"> <span class="oi oi-list-rich" aria-hidden="true"></span> Country </NavLink> </li> </ul></div>@functions {bool collapseNavMenu = true;void ToggleNavMenu(){ collapseNavMenu = !collapseNavMenu;}}
Now we have completed our cascading dropdown list application.
现在,我们已经完成了级联下拉列表应用程序。
执行演示 (Execution Demo)
Launch the application.
启动应用程序。
A web page will open as shown in the image below. The navigation menu on the left shows the navigation link for the CountryData page.
如下图所示,将打开一个网页。 左侧的导航菜单显示CountryData页面的导航链接。
Click on “country” in the navigation menu. It will redirect to the CountryData view where you can see two dropdown s— Country and Cities — on the page. Notice the URL has “/country ” appended to it as we have defined it using the @page directive.
在导航菜单中单击“国家”。 它将重定向到CountryData视图,您可以在页面上看到两个下拉列表-Country和Cities。 注意,正如我们使用@page指令定义的那样,URL后面附加了“ / country ”。
Here you can see both the dropdown lists. The Country dropdown list is already populated with the country data. If we select any country name from this dropdown, then the city dropdown will also get populated with the corresponding city data. We can also see the selected country and city values in the labels below both drop down lists.
在这里您可以看到两个下拉列表。 国家/地区下拉列表已使用国家/地区数据填充。 如果我们从此下拉列表中选择任何国家/地区名称,则城市下拉列表还将填充相应的城市数据。 我们还可以在两个下拉列表下方的标签中看到所选的国家和城市值。
托管应用 (Hosting the application)
To learn how to host a Blazor application using IIS , refer to Deploying a Blazor Application on IIS
要了解如何使用IIS托管Blazor应用程序,请参阅在IIS上部署Blazor应用程序
结论 (Conclusion)
We have learned how to create cascading dropdown lists in Blazor using Entity Framework Core database first approach with the help of Visual Studio 2017 and SQL Server 2014. Please get the source code from GitHub and play around to get a better understanding.
我们已经了解了如何在Visual Studio 2017和SQL Server 2014的帮助下使用Entity Framework Core数据库优先方法在Blazor中创建级联下拉列表。请从GitHub获取源代码,并进行尝试以获得更好的理解。
Get my book Blazor Quick Start Guide to learn more about Blazor.
获取我的书《 Blazor快速入门指南》,以了解有关Blazor的更多信息。
You can check my other articles on Blazor here
您可以在此处查看有关Blazor的其他文章
You can also find this article at C# Corner.
您也可以在C#Corner上找到此文章。
也可以看看 (See Also)
ASP.NET Core — Getting Started With Blazor
ASP.NET Core — Blazor入门
ASP.NET Core — CRUD Using Blazor And Entity Framework Core
ASP.NET Core —使用Blazor和Entity Framework Core的CRUD
ASP.NET Core — CRUD Using Angular 5 And Entity Framework Core
ASP.NET Core —使用Angular 5和实体框架Core的CRUD
ASP.NET Core — CRUD With React.js And Entity Framework Core
ASP.NET Core —使用React.js和实体框架Core的CRUD
ASP.NET Core — Using Highcharts With Angular 5
ASP.NET Core —在Angular 5中使用Highcharts
Originally published at https://ankitsharmablogs.com/
最初发布在 https://ankitsharmablogs.com/
翻译自: https://www.freecodecamp.org/news/how-to-create-a-cascading-dropdownlist-in-blazor-using-ef-core-d230bb5bff5f/