MVC5+EF6 完整教程17--升級到EFCore2.0
EF Core 2.0上周已經發布了,我們也升級到core
文章內容基於vs2017,請大家先安裝好vs2017(15.3).
本篇文章主要講下差異點,跟之前一樣的就不再重復了。
文章目錄(差異點):
一、新建項目, EF配置/使用 過程的變化
二、身份驗證方式的變化(達到類似於原form認證效果)
三、使用原生SQL方式變化
四、讀取config過程(默認取消了web.config, 改為讀 json配置文件)
一、EF使用
使用EF Core新建項目時,配置過程有一些變化。
我們先新建個項目。
選擇如下模板
一、安裝並配置好EF
1、菜單欄選擇TOOLS à NuGet Package Manager à Package Manager Console
輸入:Install-Package Microsoft.EntityFrameworkCore.SqlServer
2、建一個Model作為測試數據
打開文件夾Models, 增加類SysUser
3、新建文件夾DAL,用來放置EF相關的類。
新建Context,跟之前文章的過程類似,如下圖,不再細說。
4、給context增加DI (dependency injection, 依賴註入)
之前我們講了DI的原理與實現,ASP.NET Core默認實現了DI,服務在啟動時進行註冊,通過構造函數的方式獲取。
我們只需要按照框架需要的填空即可。
打開Startup.cs, 註冊context,如下方框處
修改配套的 DefaultConnection
打開appsettings.json文件,增加配置節:
添加測試數據,生成數據庫結構
Startup中修改Configure方法,調用剛剛的方法。
運行一下網站,可以看到數據庫和測試數據都已生成。
5、Control中使用數據
添加Control的方式也和以前一模一樣,不過第一次添加Control時會出現一個設定選項。
右鍵Controls文件夾,選擇菜單 AddàControl, 第一次會出現Add MVC Dependencies設置,我們選擇 Minimal Dependencies
添加後會出現一個txt文檔ScaffoldingReadMe.txt,可以刪除它。
我們添加一個Control來讀取數據庫中數據。
主要差異是獲得context的方式,通過構造函數註入。
之前我們都是直接new一個context, 原來:
privite XxxContext db=new XxxContext();
現在:
我們加個斷點調試下,可以看到獲得了user的列表。
另外提一下,新建Controller時,如果使用帶視圖的模板,會發現默認使用了異步的方式,類似於:
public async Task<IActionResult> Index()
{
return View(await _context.XXX.ToListAsync());
}
異步主要是針對數據庫操作,如果並發小(例如管理員的後臺管理界面),沒有必要。如果並發多,提升還是很明顯的。我們後面第三部分具體項目時會根據預設並發訪問量的大小需要選擇性使用異步的方式。
二、身份驗證
原來是在web.config中配置為form認證的,現在web.config沒有了,當然默認就不采取這種方式了。
我們來看一下ASPNETCore中如何實現身份驗證的配置。
準備工作:
先裝個包 install-package Microsoft.AspNetCore.Authentication.Cookies
再新建AccountController, 添加一個Login的Action及其配套的View用來完成登錄 .(和前面的教程做法一樣的,不再細說)
一、打開Startup.cs
1. 在ConfigureServices 中配置 Cookie 中間件
2. 在Configure中使用Cookie中間件:app.UseAuthentication();
註意:EFCore 1.1 和2.0是不一樣的,如果是1.1的版本需做如下修改(差不多兩個方法中的內容剛好調換了):
1.添加如下方框處內容,ConfiguraServices方法中啟用驗證。
2. Config方法中配置驗證相關信息
二、完成登錄功能
我們去HomeController中配置Index方法需要驗證
當再次訪問該地址時可以看到跳轉到登錄界面上了
接下來我們就完成登錄界面
Login.cshtml增加個表單
顯示如下
下面我們增加AccountController中的Login方法完成登錄。
核心就是要構建一個 ClaimsPrincipal的實例。
我直接給出具體做法,實際應用時直接修改此方法即可。
我們就不去數據庫驗證了,直接定義一個TestUser
前臺要獲取登錄的用戶名,使用 @User.Identity.Name 即可。
我們在菜單上增加一項:
<li><a>Current User: @User.Identity.Name</a></li>
結果:
另外登出方法為:
await HttpContext.SignOutAsync("MyCookieAuthenticationScheme");
比較簡單就不再演示了。
註意:1.1版本登出方法為
HttpContext.Authentication.SignOutAsync("MyCookieAuthenticationScheme ");
關於登錄說明的官方文檔:
https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/cookie
三、原生SQL
使用原生SQL分為查詢和更新兩類。
更新和之前是一樣的,可以參考我之前文章http://www.cnblogs.com/miro/p/4518811.html
代碼示例:
string sql= "DELETE FROM [SysUserRole] WHERE [SysUserID]=@userId ";
SqlParameter[] paras = new SqlParameter[]{
new SqlParameter("@userId",userId)
};
int res = _context.Database.ExecuteSqlCommand(sql, paras);
查詢之前的做法Database.SqlQuery或DbSet.SqlQuery就不能用了。
Core2.0中用FromSql返回實體,例如:
int id=1;
string sql= "SELECT * FROM SysUser WHERE ID={0}"
var user=_context.SysUsers.FromSql(sql, id); // 後面的省略
這種不具備太多實用性,因為不用SQL也可以很容易實現查詢。
下面直接給出通用的範例:
string query = @"復雜的sql語句";
SqlParameter[] paras = new SqlParameter[]{
new SqlParameter("@roleId",roleId)
}; //添加一些參數
var conn = _context.Database.GetDbConnection();
try
{
conn.Open();
using (var command = conn.CreateCommand())
{
command.CommandText = query;
command.Parameters.AddRange(paras);
DbDataReader reader = command.ExecuteReader();
// 下面處理得到的 reader,略
}
}
catch (Exception)
{
throw;
}
finally
{
conn.Close();
}
我們一般用while循環處理 得到的reader,略。
四、讀取config過程
最後再說一下配置文件的問題。
ASPNETCore默認取消了web.config, 改為讀 json配置文件。
1、我們先去appSettings.json中增加一行數據。
2、和使用context類似,Startup.cs > ConfigureServices中增加一個服務
3、Controller中使用
加個斷點調試下,可以看到,已經可以取到值了。
總結
ASPNETCore2.0做了比較大的改變,有些在1.1的用法到2.0直接就廢棄了,還是比較激進的。另外還有一些其他的小細節變化,等具體項目時碰到再說。
大家先學會怎麽使用,有空再去體會Core2.0做法的優點。
另外,關於一些Core2.0的問題可以到如下地址查看
https://github.com/aspnet/Security/issues
例如我從1.1到2.0認證方面遇到問題,解決方法就是找到了
https://github.com/aspnet/Security/issues/1310
祝學習進步:)
MVC5+EF6 完整教程17--升級到EFCore2.0