AngularJS 和 REST API: 第四部分





1.00/5 (1投票)
AngularJS 和 REST API 教程 - 第四部分。
引言
在 AngularJS 和 REST API:第二部分 中,我展示了一个名为 Airport
的数据库表,其中包含来自 https://openflights.org/data.html 的机场数据。(第三部分也使用了相同的表。)这个表有两个问题
- 由于机场所在城市的名称被完整地拼写出来,存在大量不必要的数据重复。例如,圣迭戈有三个机场,因此城市名称“
San Diego
”在表中重复了三次。消除这种冗余的过程称为 规范化。 - 数据中没有包含
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 中的 AirportEntities
和 AirportNewEntities
连接字符串,以指向您的数据库,方法是将 [YOUR_SERVER_NAME]
和 [YOUR_DATABASE_NAME]
分别设置为您的服务器名称和数据库名称。按 F6 生成项目;项目应该能够成功生成而没有错误。按 F5 以调试模式运行 AirportsAPI
项目。如 AngularJS 和 REST API:第二部分 中所述,您需要更改 ListController.js 中的 'YOUR CREDENTIALS' 以使用您的 Bing 凭据。我使用的是 Entity Framework 的数据库优先模型,因此我提供了六个 SQL 脚本来创建和填充数据库表。在 CreateAirportTable.sql、CreateCityTable.sql 和 CreateAirportTableNew.sql 脚本文件中,将 [YOUR_DATABASE_NAME]
更改为您的数据库名称,然后在 SQL Server Management Studio (SSMS) 中执行这三个脚本以创建这三个表。创建表后,您可以通过执行 AirportDataBaseLosAngeles.sql、InsertIntoCityTable.sql 和 InsertIntoAirportNewTable.sql 脚本来填充它们。
表连接
大多数读者都知道,表连接是关系数据库最强大的功能之一,用于根据相关列(在本例中为 CityId
)合并来自两个或多个表的行。为了说明这一点,以下是使用 _左连接_ 连接 AirportNew
和 City
表的 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
分别为 8
和 9
,但在 AirportNew
表中没有 CityId
为 8
或 9
的行,因此出现了如下所示的 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 会自动生成 City
和 AirportNew
类。为了实现一对多关系,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.html、AirportLocaterApproach2New.html 和 AirportLocaterApproach3New.html。与前几个项目中的 HTML 文件一样,它们分别演示了 AngularJS ng-repeat、AngularJS Autocomplete 以及 AngularJS md-tab 和 md-list 指令。在这三个文件中,我都添加了一个按钮来显示 CityId
;单击该按钮会显示来自 city
表的 City
信息,如上面的 图片 所示。
结论
表连接、外键和一对多关系的概念是使用关系数据库的关键。Entity Framework 提供了实现这些数据库功能的约定。
版本 4.0.0.0