MVC5+EF6入門教程——實現動態創建數據庫與登錄驗證


詳細步驟

  • 創建文件夾,規划好項目目錄
  • 創建相關實體類 (Data Model)
  • 創建 Database Context
  • 創建Initializer, 使用EF初始化數據庫,插入測試數據
  • 實現數據庫登錄驗證
  • 總結

一,創建文件夾,規划好項目目錄

  1.根目錄下新建一個 ViewModels文件夾:

    Models文件夾里面存放對應於數據庫表的實體;

    View中需要顯示的數據和Models中實體模型不一定能對應上, 因此需要專門給View使用的自定義數據模型,

    我們稱之為ViewModel , 放在   ViewModels文件夾里面。

  2.根目錄下新建一個DAL 文件夾:

    DAL 放置數據訪問相關類,如MyDbContext.cs, Initializer.cs

 

二,創建相關實體類 (Data Model)

  為了更加貼近真實情況,我們針對用戶建立三個相關的類。 TbUser, TbRole, TbUserRole

    TbUser Entity

    public class TbUser { public int Id { get; set; } public string UserName { get; set; } public string Password { get; set; } public string Email { get; set; } public virtual ICollection<TbUserRole> TbUserRoles { get; set; } }
View Code

    TbRole Entity

    public class TbRole { public int Id { get; set; } public string RoleName { get; set; } public string RoleDescription { get; set; } public virtual ICollection<TbUserRole> TbUserRoles { get; set; } }
View Code

    TbUserRole Entity

using System.ComponentModel.DataAnnotations.Schema;

namespace TestMVC.Models
{
    public class TbUserRole
    {
        public int Id { get; set; }
        public int UserId { get; set; }
        public int RoleId { get; set; }
        [ForeignKey("UserId")]
        public virtual TbUser TbUser { get; set; }
        [ForeignKey("RoleId")]
        public virtual TbRole TbRole { get; set; }
    }
}
View Code

  對於上面幾個類的約定和說明:

  • EF生成數據庫時,ID 屬性將會成為主鍵。(約定:EF默認會將ID或classnameID生成主鍵, MSDN建議保持風格的一致性, 都用ID或classnameID, 我們這里都用ID);
  • EF 生成數據庫時 , <navigation property name><primary key property name>這種形式的會成為外鍵. ( 約定 )

    例如外鍵 TbUserID = TbUser(navigation property)+ID(TbUser的主鍵) ;

  • 定義為virtual的幾個屬性是 navigation 屬性(virtual非必須, 只是慣例用法);

    navigation 屬性保存着其他的關聯entity(entities);

    示例中, TbUser和TbUserRole是一對多的關系, TbRole和TbUserRole也是一對多的關系;

    如果是 "多", 屬性類型就必須是List( 這里用的是ICollection);

三,創建 Database Context

  1.通過NuGet安裝Entity Framework

  

  2.創建類 MyDbContext.cs , 讓他繼承自System.Data.Entity.DbContext, 我們用這個類完成EF的功能:

  主要做下面三件事:

    • 為每個entity set創建一個DbSet

      在EF中,通常情況下一個entity set對應數據庫中的一張表,一個entity對應表中的一行。

    • 指定一個連接字符串

      構造函數中的 base("MyDbContext") 。

      默認情況下和類名一樣,即MyDbContext我們顯式的給他指定出來。

    • 指定單數形式的表名

      modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

      默認情況下會生成復數形式的表,如TbUsers

      PS: 表名用單復數形式看各自的習慣,沒有明確的規定。有的公司表名全用單數,有的公司根據表的意思,有單數也有復數。

  MyDbContext.cs

    public class MyDbContext:DbContext
    {
        public MyDbContext()
            : base("MyDbContext")
        { }
        public IDbSet<TbUser> TbUsers { get; set; }
        public IDbSet<TbRole> TbRoles { get; set; }
        public IDbSet<TbUserRole> TbUserRoles { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //因為表名稱默認為復數形式,這里是移除復數形式,所以為單數形式生成
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }
View Code

  3.配合上面第2點,需要web.config中的數據庫連接字符串:

  如下圖,添加connectionStrings節點。注意要web.config中要加上紅字部分(表示連接的是Sql Server數據庫),不然會出錯。

  <connectionStrings>
      <add name="MyDbContext" connectionString="Data Source=.;

   database=TestMvc;uid=sa;pwd=123456;AttachDBFilename=|DataDirectory|\TestMVC.mdf;" providerName="System.Data.SqlClient"/>
   </connectionStrings>

  PS: AttachDBFilename=|DataDirectory|\TestMVC.mdf設定了數據庫文件的存放位置:在項目根目錄的App_Data文件夾下

  

四,創建Initializer, 使用EF初始化數據庫,插入測試數據

  PS:EF可以以多種方式建立數據庫,我們暫時采用 第一次運行程序時新建數據庫,插入測試數據; model改變(和database不一致)時刪除重建數據庫,插入測試數據。暫時不用管數據丟失的問題,直接drop and re-create比較方便。等后面單獨拿一篇出來講解生產環境中如何不丟失數據修改數據庫。

  1.新建類Initializer.cs來完成這個工作:

   Seed方法用我們之前定義的database context(即MyDbContext) 作為參數,通過這個context將entities添加到database中去;

   從上面代碼可以看出, Seed方法對每一個entity的類型;

   創建一個colletion à 添加到適當的 DbSet property à 保存到數據庫。

  Initializer.cs

    public class Initializer:DropCreateDatabaseIfModelChanges<MyDbContext>
    {
        protected override void Seed(MyDbContext context)
        {
            var tbUsers = new List<TbUser> { 
                new TbUser{UserName="張三",Password="zhangsan",Email="zhangsan@163.com"},
                new TbUser{UserName="李四",Password="lisi",Email="lisi@163.com"}
            };
            tbUsers.ForEach(u => context.TbUsers.Add(u));

            var tbRoles = new List<TbRole> { 
                new TbRole{RoleName="管理員",RoleDescription="管理員具有最高權限來對系統進行管理"},
                new TbRole{RoleName="一般用戶",RoleDescription="一般用戶具有一些基本的操作權限"}
            };
            tbRoles.ForEach(r => context.TbRoles.Add(r));
            var tbUserRole = new List<TbUserRole> { 
                new TbUserRole{UserId=1,RoleId=1},
                new TbUserRole{UserId=1,RoleId=2},
                new TbUserRole{UserId=2,RoleId=2}
            };
            tbUserRole.ForEach(ur => context.TbUserRoles.Add(ur));
            context.SaveChanges();
        }
    }
View Code

  2.修改web.config, 通知EF使用我們剛剛寫好的Initializer類,找到entityFramework配置節,添加下圖方框處內容:

  

   context 配置節中, type 的值對應 (context class的完整描述,程序集)

  databaseInitializer 配置節中 , type 的值對應 (initializer class 的完整描述,程序集)

  PS: 如果你不想EF使用某個context, 可以在context節點里面添加屬性disableDatabaseInitialization="true";

五,實現數據庫登錄驗證

  現在EF一切就緒了,運行程序,當第一次連接數據庫時,EF比較model(AccountContext和entity classes) 和database. 如果兩邊不一致,程序將會drop and re-create(刪除並新建)數據庫,因為目前我們還沒有連接數據庫的操作,所以EF還沒發揮作用。在第一次連接數據庫時才會生效

  AccountController.cs

    public class AccountController : Controller
    {
        private MyDbContext db = new MyDbContext();
        // GET: Account
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Login()
        {
            ViewBag.LoginState = "登錄前...";
            return View();
        }
        [HttpPost]
        public ActionResult Login(TbUser user)
        {
            var userinfo = db.TbUsers.FirstOrDefault(u => u.Email == user.Email && u.Password == user.Password);
            if (userinfo != null)
                ViewBag.LoginState = userinfo.UserName+"登錄后...";
            else
                ViewBag.LoginState = user.Email + "用戶不存在...";
            return View();
        }
    }
View Code

  Login.cshtml

@model TestMVC.Models.TbUser
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Login</title>
</head>
<body>
    <div> 
        @ViewBag.LoginState
        @using(Html.BeginForm("Login","Account",FormMethod.Post)){
            @Html.LabelFor(u=>u.Email)<br />
            @Html.TextBoxFor(u=>u.Email)<br />
            @Html.LabelFor(u => u.Password)<br />
            @Html.PasswordFor(u => u.Password)<br />
            <input type="submit" value="登錄" />
        }
    </div>
</body>
</html>
View Code

  然后運行Login.cshtml頁面,執行效果下:

  

  

  

六,總結

OK,到此為止,我們搭建好了EF框架,進行了數據庫的初始化,查詢了一條用戶信息。

需要說明的是,現在的登錄功能還比較簡陋,不是真正的登錄功能(例如輸入項還缺少驗證,密碼還沒有加鹽),只是為了說明EF的用法。

最后再回顧下本章的重點:掌握使用EF開發的整個過程。

創建Data Modelà創建Database Context à創建databaseInitializerà配置entityFramework的context配置節

  希望大家能清晰的了解上面整個過程,理解每一個過程的作用。

源碼下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM