65.9K
CodeProject 正在变化。 阅读更多。
Home

AngularJS 和 REST API: 第四部分

starIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

1.00/5 (1投票)

2018 年 7 月 12 日

CPOL

5分钟阅读

viewsIcon

9713

downloadIcon

119

AngularJS 和 REST API 教程 - 第四部分。

引言

AngularJS 和 REST API:第二部分 中,我展示了一个名为 Airport 的数据库表,其中包含来自 https://openflights.org/data.html 的机场数据。(第三部分也使用了相同的表。)这个表有两个问题

  1. 由于机场所在城市的名称被完整地拼写出来,存在大量不必要的数据重复。例如,圣迭戈有三个机场,因此城市名称“San Diego”在表中重复了三次。消除这种冗余的过程称为 规范化
  2. 数据中没有包含 City 所在的州。当然,通常可以从城市名称推断出州,例如,几乎所有人都知道洛杉矶在加利福尼亚州,但如果城市是斯普林菲尔德呢?(美国有 30 多个斯普林菲尔德!)

在第四部分,我将解决这两个问题。为了解决第一个问题,我创建了一个名为 City 的新表,其中每一行包含城市信息。City 表中的每一行都有一个唯一的 ID,CityId,然后该 ID 将用于标识新的机场表 AirportNew 中的城市。在数据库术语中,CityId 是一个 _外键_,这种关系是 _一对多_ 的,因为一个城市可以有多个机场(例如圣迭戈或萨克拉门托),但一个机场只能属于一个城市。下面将描述如何在 Entity Framework 中配置一对多关系。为了解决第二个问题,州信息(以及城市名称、县、经度和纬度)包含在 City 表中。

Using the Code

下载 AirportDatabaseProjectPart4.zip 文件并解压缩。它包含一个名为 AngularJS_REST_API_AirportLocator 的目录,其中包含 JavaScript 和 HTML 文件、六个 SQL 脚本文件以及 Visual Studio 2015 项目 AirportsAPI。使用 Visual Studio 打开 AirportsAPI 项目。您需要更改 Web.config 中的 AirportEntitiesAirportNewEntities 连接字符串,以指向您的数据库,方法是将 [YOUR_SERVER_NAME][YOUR_DATABASE_NAME] 分别设置为您的服务器名称和数据库名称。按 F6 生成项目;项目应该能够成功生成而没有错误。按 F5 以调试模式运行 AirportsAPI 项目。如 AngularJS 和 REST API:第二部分 中所述,您需要更改 ListController.js 中的 'YOUR CREDENTIALS' 以使用您的 Bing 凭据。我使用的是 Entity Framework 的数据库优先模型,因此我提供了六个 SQL 脚本来创建和填充数据库表。在 CreateAirportTable.sqlCreateCityTable.sqlCreateAirportTableNew.sql 脚本文件中,将 [YOUR_DATABASE_NAME] 更改为您的数据库名称,然后在 SQL Server Management Studio (SSMS) 中执行这三个脚本以创建这三个表。创建表后,您可以通过执行 AirportDataBaseLosAngeles.sqlInsertIntoCityTable.sqlInsertIntoAirportNewTable.sql 脚本来填充它们。

表连接

大多数读者都知道,表连接是关系数据库最强大的功能之一,用于根据相关列(在本例中为 CityId)合并来自两个或多个表的行。为了说明这一点,以下是使用 _左连接_ 连接 AirportNewCity 表的 SQL,它返回左表(AirportNew)的所有记录,以及右表(City)的匹配记录。由于 AirportNew 表中的每个 CityId 都在 City 表中有对应的 CityId,因此没有 NULL 行。

select AN.Name, AN.CityId, AN.ICAO, AN.Latitude, AN.Longitude, City.Placename as 'City Name',
City.AdminName2 as County, City.AdminCode1 as State from AirportNew AN left join City
on AN.CityId = City.CityId
名称 CityId ICAO 纬度 经度 City Name County 状态
Hayward Executive Airport 1 KHWD 37.659199 -122.122002 Hayward Alameda CA
Livermore Municipal Airport 2 KLVK 37.693401 -121.820000 Livermore Alameda CA
Chico Municipal Airport 4 KCIC 39.795399 -121.858002 Chico Butte CA
Buchanan Field 5 KCCR 37.98970 -122.056999 Concord Contra Costa CA
...              

正如您所期望的,_右连接_ 会返回右表(City)的所有记录,以及左表(AirportNew)的匹配记录。但是,由于 City 表中有一些 CityId 没有在 AirportNew 表中引用,因此存在一些 NULL 行。换句话说,“Coalinga”和“Huron”这两个城市在我们的 City 表中,CityId 分别为 89,但在 AirportNew 表中没有 CityId89 的行,因此出现了如下所示的 NULL 行。

select AN.Name, AN.CityId, AN.ICAO, AN.Latitude, AN.Longitude, City.Placename as 'City Name',
City.AdminName2 as County, City.AdminCode1 as State from AirportNew AN right join City
on AN.CityId = City.CityId
名称 CityId ICAO 纬度 经度 City Name County 状态
Buchanan Field 5 KCCR 37.989700 -122.056999 Concord Contra Costa CA
Jack Mc Namara Field Airport 6 KCEC 41.780201 -124.237000 Crescent City Del Norte CA
Lake Tahoe Airport 7 KTVL 38.89390 -119.995003 South Lake Tahoe El Dorado CA
NULL NULL NULL NULL NULL Coalinga Fresno CA
NULL NULL NULL NULL NULL Huron Fresno CA
...              

在 Entity Framework 中配置一对多关系

由于我使用的是 Entity Framework 的 数据库优先 模型,因此我添加了一个 ADO.NET 实体数据模型,Visual Studio 会自动生成 CityAirportNew 类。为了实现一对多关系,Entity Framework 会在 City 类中创建一个 _集合导航属性_ public virtual ICollection<AirportNew> AirportsNew

public partial class City
{
	public City()
	{
		this.AirportsNew = new HashSet<AirportNew>();
	}
	public int CityId { get; set; }
	(remaining properties)
	...
	public virtual ICollection<AirportNew> AirportsNew { get; set; }
}

它会在 AirportNew 类中创建一个引用导航属性 public virtual City City

public partial class AirportNew
{
	public int ID { get; set; }
	public int VendorID { get; set; }
	public string Name { get; set; }

	public int CityId { get; set; }
	public string IATA { get; set; }
	(remaining properties)
	...

	public virtual City City { get; set; }
}

API

第四部分的 API 与 第三部分 相同,只是数据现在从 AirportsNew 表中获取,并且 API 中添加了“New”一词。例如,AirportsByRect 现在是 AirportsNewByRect: curl -X GET https://:55213/api/AirportsNewByRect/34.4/-119.3/33.7/-117.9/

我在 AngularJS_REST_API_AirportLocator 中还创建了新的 HTML 文件来使用 AirportNew 表;新的 HTML 文件是 AirportLocaterApproach1New.htmlAirportLocaterApproach2New.htmlAirportLocaterApproach3New.html。与前几个项目中的 HTML 文件一样,它们分别演示了 AngularJS ng-repeat、AngularJS Autocomplete 以及 AngularJS md-tab 和 md-list 指令。在这三个文件中,我都添加了一个按钮来显示 CityId;单击该按钮会显示来自 city 表的 City 信息,如上面的 图片 所示。

结论

表连接、外键和一对多关系的概念是使用关系数据库的关键。Entity Framework 提供了实现这些数据库功能的约定。

版本 4.0.0.0

© . All rights reserved.