創(chuàng)建數(shù)據(jù)項目
為了給后續(xù)的項目開發(fā)提供一個層次分明的代碼結(jié)構(gòu),這里我們在解決方案下新建一個數(shù)據(jù)項目WebAPIData
姨谷。
選擇控制臺應(yīng)用程序,如圖:
在WebAPIData
項目下新建三個文件夾Entities
纵柿、Mappers
明刷、Migrations
,將會分別存放數(shù)據(jù)實體類树瞭、數(shù)據(jù)映射配置以及數(shù)據(jù)遷移配置拇厢;刪除自動生成的Program.cs
類。
下面我們介紹如何運用Entity Framework生成數(shù)據(jù)表晒喷。
在Entities
文件夾下新建實體類Student.cs
孝偎,我們需求的字段的姓名、學(xué)號凉敲、班級衣盾、電話,代碼如下:
public class Student
{
public int ID { get; set; }
public string Name { get; set; }
public string StuID { get; set; }
public string Class { get; set; }
public string Phone { get; set; }
}
在Mappers
文件夾中新建StudentMapper,cs
類爷抓,我們將在該類中配置數(shù)據(jù)表的字段約束势决。在此,我們需要引用到Entity Framework組件蓝撇,如下圖:
引用完成后果复,我們可以看到
Entity Framework
和Entity Framework.SqlServer
包含到引用中。StudentMapper,cs
類中的代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity.ModelConfiguration;
using WebAPIData.Entities;
using System.ComponentModel.DataAnnotations.Schema;
namespace WebAPIData.Mappers
{
class StudentMapper:EntityTypeConfiguration<Student>
{
public StudentMapper()
{
this.ToTable("Student");
this.HasKey(c => c.ID); //主鍵
this.Property(c => c.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); //主鍵自增長
this.Property(c => c.ID).IsRequired();
this.Property(c => c.Name).IsRequired(); //字段非空
this.Property(c => c.Name).HasMaxLength(10); //設(shè)定字段最大長度
this.Property(c => c.StuID).IsRequired();
this.Property(c => c.StuID).HasMaxLength(20);
this.Property(c => c.Class).IsOptional(); //字段可以為空
this.Property(c => c.Phone).IsRequired();
this.Property(c => c.Phone).HasMaxLength(20);
}
}
}
Code First存在利用數(shù)據(jù)屬性DataAnnotation和Fluent API兩種配置數(shù)據(jù)庫映射的方式渤昌。DataAnnotation配置方式是將與數(shù)據(jù)庫映射相關(guān)的配置標(biāo)簽加到定義實體和值對象的類和類中的屬性上虽抄,F(xiàn)luent API是通過在繼承DbContext類中定義數(shù)據(jù)庫配置的方式的。
在這里我們采用Fluent API的方式独柑,因為我們后續(xù)的開發(fā)會涉及到主外鍵配置以及一對一迈窟、多對一、一對多忌栅、多對都的映射關(guān)系车酣,采用Fluent API方式可以保證我們結(jié)構(gòu)清晰。DataAnnotation配置數(shù)據(jù)庫映射的例子如下索绪,在此我們不再贅述湖员。
[Required]
public string Name { get; set; }
在WebAPIData
下新建WebAPIContest.cs
類,進(jìn)行相應(yīng)的配置,作為數(shù)據(jù)的上下文類者春,代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WebAPIData.Entities;
using WebAPIData.Mappers;
using System.Data.Entity;
using WenAPIData.Migrations;
namespace WebAPIData
{
/*
* 1.把我們定義的POCO類作為DBSet的屬性對外公開破衔,這意味著每一個POCO類都將被轉(zhuǎn)化為數(shù)據(jù)庫中的表
2.重寫OnModelCreating方法將我們?yōu)镻OCO類自定義的映射規(guī)則添加到DbModelBuilder配置中
*
*/
public class WebAPIContext:DbContext
{
public WebAPIContext()
: base("WebAPIConnection")
{
Configuration.ProxyCreationEnabled = false;
Configuration.LazyLoadingEnabled = false; //延時加載
Database.SetInitializer(new MigrateDatabaseToLatestVersion<WebAPIContext, Configuration>());
//為數(shù)據(jù)庫配置初始化和遷移策略,如果模型的屬性被改變(添加了新的屬性)钱烟,就把數(shù)據(jù)庫遷移到最新版本。
}
public IDbSet<Student> Students { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new StudentMapper());
base.OnModelCreating(modelBuilder);
}
}
}
在Migrations
文件夾下新建Configuration.cs
文件,在此將進(jìn)行數(shù)據(jù)庫的遷移配置拴袭,可以在Entity Framework
使用Code First Migration來用測試數(shù)據(jù)建立數(shù)據(jù)庫读第。代碼如下:
namespace WenAPIData.Migrations
{
using WebAPIData.Entities;
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<WebAPIData.WebAPIContext>
{
public Configuration()
{
/**
* 在構(gòu)造函數(shù)中,我們設(shè)置AutomaticMigrationsEnabled 屬性為true拥刻,
* 那么就意味著EF會為我們自動遷移數(shù)據(jù)庫而不考慮版本問題怜瞒。
* 同時我們把AutomaticMigrationDataLossAllowed屬性也設(shè)為true但這樣做在開發(fā)環(huán)境中是很危險的,
* 因為如果這個屬性設(shè)為false時般哼,一旦數(shù)據(jù)庫在自動遷移時發(fā)生數(shù)據(jù)丟失吴汪,那么就會拋出一個異常。
*
* */
AutomaticMigrationsEnabled = true;
this.AutomaticMigrationDataLossAllowed = true;
}
protected override void Seed(WebAPIData.WebAPIContext context)
{
//可以在此部分添加數(shù)據(jù)實例
}
}
}
到現(xiàn)在蒸眠,我們數(shù)據(jù)實體已經(jīng)配置完畢漾橙,下面我們在WebAPIDemo
項目中,創(chuàng)建Web API控制器楞卡。首先霜运,我們需要在WebAPIDemo
加入對WebAPIData
項目的引用。
應(yīng)用完成后先編譯下項目蒋腮,我們將開始調(diào)用
WebAPIData
中的類淘捡。
下面將添加支持CRUD(create, read, update 和 delete)的Web API 控制器。這些控制器使用Entity Framework來同數(shù)據(jù)庫層交流池摧,如圖:
選擇包含操作的Web API 2控制器(使用Entity Framework)焦除,如圖:
在在Add Controller對話框中,執(zhí)行以下操作:
1.在模型類下拉框中作彤,選擇Student類(如果你沒有在下拉框中看到它踢京,請確保已經(jīng)編譯了這個項目)
2.數(shù)據(jù)庫上下文類選擇WebAPIContext類
單擊添加,控制器類就生成了宦棺,包含基本的GET
瓣距、POST
、PUT
代咸、DELETE
方法蹈丸,代碼如下:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Description;
using WebAPIData;
using WebAPIData.Entities;
namespace WebAPIDemo.Controllers
{
public class StudentsController : ApiController
{
private WebAPIContext db = new WebAPIContext();
// GET: api/Students
public IQueryable<Student> GetStudents()
{
return db.Students;
}
// GET: api/Students/5
[ResponseType(typeof(Student))]
public IHttpActionResult GetStudent(int id)
{
Student student = db.Students.Find(id);
if (student == null)
{
return NotFound();
}
return Ok(student);
}
// PUT: api/Students/5
[ResponseType(typeof(void))]
public IHttpActionResult PutStudent(int id, Student student)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != student.ID)
{
return BadRequest();
}
db.Entry(student).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!StudentExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
// POST: api/Students
[ResponseType(typeof(Student))]
public IHttpActionResult PostStudent(Student student)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Students.Add(student);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = student.ID }, student);
}
// DELETE: api/Students/5
[ResponseType(typeof(Student))]
public IHttpActionResult DeleteStudent(int id)
{
Student student = db.Students.Find(id);
if (student == null)
{
return NotFound();
}
db.Students.Remove(student);
db.SaveChanges();
return Ok(student);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool StudentExists(int id)
{
return db.Students.Count(e => e.ID == id) > 0;
}
}
}
當(dāng)然了,我們在實際的項目應(yīng)用中需要重寫需要的CRUD方法呐芥,因為本文是簡單的demo實現(xiàn)逻杖,所以在此不再贅述控制器中CRUD方法的編寫。
下面將初始化我們的數(shù)據(jù)庫思瘟,首先需要在WebAPIDemo
中的Web.config
文件增加數(shù)據(jù)庫的連接字符串荸百,如圖:
其中,字符串為:
<connectionStrings>
<add name="WebAPIConnection" connectionString="Data Source=DESKTOP-MDNON6P; User=name;Password=passwd;Initial Catalog=WebAPIDemo" providerName="System.Data.SqlClient" />
</connectionStrings>
上面的WebAPIDemo
即為數(shù)據(jù)庫名滨攻。
配置完成后够话,使用Code First Migration來用測試數(shù)據(jù)建立數(shù)據(jù)庫蓝翰。在工具目錄下選擇NuGet程序包管理器,然后選擇程序包管理控制臺女嘲。
在包管理控制臺窗口畜份,輸入以下命令:
Add-Migration Initial
Update-Database
第一條命令生成用于創(chuàng)建數(shù)據(jù)庫的代碼,第二條命令執(zhí)行那些代碼欣尼。
數(shù)據(jù)庫創(chuàng)建完成爆雹,我們打開SQL Server即可看到WebAPIDemo數(shù)據(jù)庫。
我們在數(shù)據(jù)表中隨意插入一些數(shù)據(jù)進(jìn)行測試愕鼓,如圖:
將WebAPIDemo
設(shè)為啟動項目钙态,運行,我們調(diào)用Get方法進(jìn)行測試菇晃,如圖:
測試成功册倒。可以看到上面調(diào)用API返回的格式是XML格式谋旦,我們將其轉(zhuǎn)換為Json格式剩失。在WebAPIDemo
項目中APP_Start
文件夾下的WebapiConfig.cs
類中添加代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace WebAPIDemo
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服務(wù)
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// New code:
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.Objects; //把Json格式化器設(shè)置為防止對對象引用
config.Formatters.Remove(config.Formatters.XmlFormatter);
}
}
}
再次調(diào)用Get方法進(jìn)行測試,返回Json格式如下:
至此册着,一個簡單的從數(shù)據(jù)庫獲取數(shù)據(jù)封裝成REST風(fēng)格服務(wù)的WebAPI已經(jīng)完成拴孤。
下面將簡單介紹下如何使用Vue.js解析Wen API返回的數(shù)據(jù),也會對數(shù)據(jù)的雙向綁定也會做一個簡單的介紹甲捏。