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

来源:http://www.cnblogs.com/myindex/archive/2016/05/06/5467229.html
-Advertisement-
Play Games

詳細步驟 創建文件夾,規劃好項目目錄 創建相關實體類 (Data Model) 創建 Database Context 創建Initializer, 使用EF初始化資料庫,插入測試數據 實現資料庫登錄驗證 總結 一,創建文件夾,規劃好項目目錄 1.根目錄下新建一個 ViewModels文件夾: Mo ...


詳細步驟

  • 創建文件夾,規劃好項目目錄
  • 創建相關實體類 (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

    public class TbUserRole
    {
        public int Id { get; set; }
        public int UserId { get; set; }
        public int RoleId { get; set; }
        public virtual TbUser TbUser { get; set; }
        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="[email protected]"},
                new TbUser{UserName="李四",Password="lisi",Email="[email protected]"}
            };
            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配置節

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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、簡單裝飾器: 執行步驟: 1、@W1 執行W1,把自己裝飾的函數的函數名當做參數,即@W1 等價於W1(show)。 show()函數重新定義,即重新定義的show()函數等價於W1(show)返回值。 在重新定義的show()函數中去執行之前定義的函數。 二、帶參數裝飾器: 執行步驟: 1、執 ...
  • 採用gradle構建和發佈bboss版本及從maven中央庫下載bboss方法介紹 1.概述 bboss是國內最早採用gradle來構建和發佈版本的開源框架之一,那麼gradle是個什麼東東?以下公式可以大概表述一下意思: gradle=ant+maven 尤其是通過gretty插件直接可以在ecl ...
  • A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ num[i+1], find a peak element and return its inde ...
  • 如果有介面,寫在介面方法上即可。滑鼠滑過方法名時時會顯示 如果沒有介面,寫在每個方法上方。 eclipse 分三步 ① 找到方法,並將游標移動至方法名的上方 ②/** ③回車 那,效果是醬紫 ...
  • 本來用之前也過的堆直接實現比較好,這裡我直接重新寫一了函數融入進去了 註釋部分的代碼,是用來進行哈夫曼編碼的,這種編碼方式就不需要使用三叉鏈的樹了(帶有parent指針的三叉樹) ...
  • 05年第一次接觸要做彩票項目的客戶,見面談了下,客戶給了一些各彩種各玩法的獎金文檔,並給了一個正在運營的彩票網站,客戶要求我們對照功能上評估工作量然後報價。 半個月後再次見面,通過評估後報價7W(當時客戶只要求做,重慶、天津、江西以及廣東、江西、山東11選、福彩3D、上海時時樂、北京快樂8)。敲定價 ...
  • 好書不能只讀一遍,這兩天又翻看了一遍《你必須知道的.NET》,重溫了下基礎,重溫了下經典,簡單記錄了下來。 記憶體分配:CLR 管理記憶體的區域,主要有三塊,分別為: 線程的堆棧,用於分配值類型實例。堆棧主要由操作系統管理,而不受垃圾收集器的控制,當值類型實例所在方法結束時,其存儲單位自動釋放。棧的執行 ...
  • 剛開始接觸.NET很疑惑,看完視頻也不是太懂,通過總結和反覆,從概括和概念入手,慢慢變得清晰了。這篇博客主要是我對.NET基礎知識的瞭解,算作積累吧。 .NET框架體繫結構 由四個主要部分組成 公共語言運行時(CLR)是.NET框架應用程式的執行引擎..NET框架的關鍵作用在於,它提供了一個跨編程語 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...