ASP.NET Web API 入門實戰(zhàn)(2)--處理數(shù)據(jù)

創(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 FrameworkEntity 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瓣距、POSTPUT代咸、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ù)的雙向綁定也會做一個簡單的介紹甲捏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末演熟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子司顿,更是在濱河造成了極大的恐慌芒粹,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件大溜,死亡現(xiàn)場離奇詭異化漆,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)钦奋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門座云,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人付材,你說我怎么就攤上這事朦拖。” “怎么了厌衔?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵璧帝,是天一觀的道長。 經(jīng)常有香客問我富寿,道長睬隶,這世上最難降的妖魔是什么锣夹? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮理疙,結(jié)果婚禮上晕城,老公的妹妹穿的比我還像新娘泞坦。我一直安慰自己窖贤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布贰锁。 她就那樣靜靜地躺著赃梧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪豌熄。 梳的紋絲不亂的頭發(fā)上授嘀,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音锣险,去河邊找鬼蹄皱。 笑死,一個胖子當(dāng)著我的面吹牛芯肤,可吹牛的內(nèi)容都是我干的巷折。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼崖咨,長吁一口氣:“原來是場噩夢啊……” “哼锻拘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起击蹲,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤署拟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后歌豺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體推穷,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年类咧,在試婚紗的時候發(fā)現(xiàn)自己被綠了馒铃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡轮听,死狀恐怖骗露,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情血巍,我是刑警寧澤萧锉,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站述寡,受9級特大地震影響柿隙,放射性物質(zhì)發(fā)生泄漏叶洞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一禀崖、第九天 我趴在偏房一處隱蔽的房頂上張望衩辟。 院中可真熱鬧,春花似錦波附、人聲如沸艺晴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽封寞。三九已至,卻和暖如春仅财,著一層夾襖步出監(jiān)牢的瞬間狈究,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工盏求, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留抖锥,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓碎罚,卻偏偏與公主長得像磅废,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子魂莫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容