1. 程式人生 > >使用EntityFramework 6 操作 MySql (DB First)

使用EntityFramework 6 操作 MySql (DB First)

軟體環境

開發環境:VS 2017
.NET Framework: 4.6.1
MySQL: 8.0
MySQL Connector Net:8.0.12
MySQL for Visual Studio:1.2.8

建立測試資料庫

建立資料庫efdemo並建立兩張表,user和role

/*
Navicat MySQL Data Transfer

Source Server         : localhost_3306
Source Server Version : 80012
Source Host           : localhost:3306
Source Database       : efdemo

Target Server Type    : MYSQL
Target Server Version : 80012
File Encoding         : 65001

Date: 2018-09-14 12:09:01
*/
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for role -- ---------------------------- DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `role_id` int(11) NOT NULL, `role_name` varchar(255) DEFAULT NULL, PRIMARY KEY (`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE
=utf8mb4_0900_ai_ci;
-- ---------------------------- -- Records of role -- ---------------------------- INSERT INTO `role` VALUES ('0', '管理員'); INSERT INTO `role` VALUES ('1', '遊客'); -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`
;
CREATE TABLE `user` ( `user_id` int(11) NOT NULL, `user_name` varchar(255) DEFAULT NULL, `role_id` int(11) DEFAULT NULL, PRIMARY KEY (`user_id`), KEY `FK_USER_ROLE` (`role_id`), CONSTRAINT `FK_USER_ROLE` FOREIGN KEY (`role_id`) REFERENCES `role` (`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('0', 'alistair', '0'); INSERT INTO `user` VALUES ('1', 'guest', '1');

建立測試工程

建立一個名為EFMySqlDemo的控制檯專案

引用EF Core 及 工具包

專案引用 Pomelo.EntityFrameworkCore.MySql
在程式包管理器控制檯中輸入以下命令

Install-Package Pomelo.EntityFrameworkCore.MySql
Install-Package Microsoft.EntityFrameworkCore.Tools

通過命令建立實體

同樣在程式包管理器控制檯中輸入以下命令:

Scaffold-DbContext "Server=localhost;Port=3306;DataBase=efdemo;User=root;[email protected];" Pomelo.EntityFrameworkCore.MySql -OutputDir Models

該命令傳遞了資料庫的連線字串,和實體輸出路徑(Models)

執行完成後,可以看到,在專案中新生成了一個Models資料夾,其中包含了Context和兩個表的實體:

到此為止,DBFirst已經完成,可以通過操作efdemoContext來進行資料的相關操作。

例如我們查詢userId為0的使用者

namespace EFMySqlDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            efdemoContext context = new efdemoContext();
            User user = context.User.Find(0);
            Console.WriteLine(user.UserName);
            Console.Read();
        }
    }
}

執行後將會打印出對應UserName。

由於User表和Role表有包含一個外來鍵,所以在實體中我們也可以看到User物件裡面包含了Role物件。

public partial class User
    {
        public int UserId { get; set; }
        public string UserName { get; set; }
        public int? RoleId { get; set; }

        public Role Role { get; set; } //包含了Role物件
    }

現在我們不僅想要獲得使用者名稱,還想要獲得當前使用者的角色名,那麼修改程式碼為:

 class Program
    {
        static void Main(string[] args)
        {
            efdemoContext context = new efdemoContext();
            User user = context.User.Find(0);
            Console.WriteLine(user.UserName);
            Console.WriteLine(user.Role.RoleName);
            Console.Read();
        }
    }

執行後會報異常,原因是在資料通過EF對映的時候,預設情況下並不會自動加入外來鍵資訊。

筆者下面使用Repository的模式來搭建資料層。

建立Repository

引用UnitOfWork,同樣在程式包管理器中執行命令,來引入類庫

Install-Package Microsoft.EntityFrameworkCore.UnitOfWork

引用完成之後,我們修改程式碼:

    class Program
    {
        static void Main(string[] args)
        {
            efdemoContext context = new efdemoContext();
            User user1 = context.User.Find(0);
            Console.WriteLine(user1.UserName);
            if (user1.Role != null)
            {
                Console.WriteLine(user1.Role.RoleName);
            }
            else
            {
                Console.WriteLine("Role 物件為空");
            }

            Console.WriteLine("--------------------------");
            Repository<User> repository = new Repository<User>(context);
            User user2 = repository.GetFirstOrDefault(
                predicate: u => u.UserId == 0,
                include: source => source.Include(s => s.Role));
            Console.WriteLine(user2.UserName);
            Console.WriteLine(user2.Role.RoleName);
            Console.Read();
        }
    }

列印結果為: