一:背景 1.講故事 最近分享了好幾篇關於 非托管記憶體泄漏 的文章,有時候就是這麼神奇,來求助的都是這類型的dump,一飲一啄,莫非前定。讓我被迫加深對 NT堆, 頁堆 的理解,這一篇就給大家再帶來一篇記憶體泄漏。 前段時間有位朋友找到我,說他的程式出現了非托管泄漏,某一塊的操作會導致非托管記憶體上漲的 ...
學習ASP.NET Core Blazor編程系列一——綜述 學習ASP.NET Core Blazor編程系列二——第一個Blazor應用程式(上) 學習ASP.NET Core Blazor編程系列二——第一個Blazor應用程式(中)
學習ASP.NET Core Blazor編程系列二——第一個Blazor應用程式(下)
在學習ASP.NET Core Blazor編程系列三——實體 這篇文章中我們創建了資料庫上下文BookContex類,這個類就是用於處理資料庫連接和將Book實體對象映射到資料庫表(Book)記錄。資料庫上下文(BookContext)是在Program.cs文件的builder.Services.AddDbContextFactory方法中向依賴關係註入容器進行註冊,具體代碼如下:
builder.Services.AddDbContextFactory<BookContext>(opt =>
opt.UseSqlServer(ConfigHelper.Configuration["ConnectionStrings:BookContext"]));
為了進行本地開發,我們在appsettings.json 文件中配置資料庫連接字元串,資料庫連接配置如下:
"ConnectionStrings": {
"BookContext": "Server=.;Database=LeaseBook;Trusted_Connection=True;
MultipleActiveResultSets=true"
}
將應用程式部署到測試或生產伺服器時,可以修改Appsettings.json文件中上將配置,將資料庫連接字元串設置為真正的SQL伺服器。
在學習ASP.NET Core Blazor編程系列四——遷移 這篇文章中我們通過EF Core提供的遷移功能,創建了資料庫表。
在學習ASP.NET Core Blazor編程系列五——列表頁面 這篇文章我們創建了圖書列表頁面,不過由於資料庫中沒有數據,我們的圖書列表頁面上也是一片空白沒有數據顯示。
今天的這篇文章,我們將通過EF Core6提供的功能,向資料庫表Book中添加初始數據。
一、給資料庫添加初始數據
在Visual Studio 2022 的解決方案資源管理器中,使用滑鼠左鍵選中Models文件,然後點擊滑鼠右鍵,在彈出菜單中選擇“添加--》類”,創建一個新的類文件,命名為SeedData。具體代碼如下:
using Microsoft.EntityFrameworkCore;
namespace BlazorAppDemo.Models
{
public class SeedData
{
public static void Initialize(IServiceProvider serviceProvider)
{
using (var context = new BookContext(serviceProvider.
GetRequiredService<DbContextOptions<BookContext>>()))
{
// Look for any Books.
if (context.Book.Any())
{
return; // DB has been seeded
}
context.Book.AddRange(
new Book
{
Name = "Python編程 從入門到實踐",
ReleaseDate = DateTime.Parse("2018-1-12"),
Author = "埃里克·馬瑟斯",
Price = 75.99M,
StockQty=10,
Qty=0,
TotalPages=445,
Type=""
},
new Book
{
Name = "Java編程的邏輯",
ReleaseDate = DateTime.Parse("2018-1-13"),
Author = "馬俊昌",
Price = 48.99M,
StockQty = 12,
Qty = 0,
TotalPages = 675,
Type = ""
},
new Book
{
Name = "統計思維:大數據時代瞬間洞察因果的關鍵技能",
ReleaseDate = DateTime.Parse("2017-12-23"),
Author = "西內啟",
Price = 39.99M,
StockQty = 20,
Qty = 0,
TotalPages = 330,
Type = ""
},
new Book
{
Name = "微信營銷",
ReleaseDate = DateTime.Parse("2018-01-05"),
Author = "徐林海",
Price = 33.99M,
StockQty = 30,
Qty = 0,
TotalPages = 266,
Type = ""
}
);
context.SaveChanges();
}
}
}
}
以下語句的作用是 如果資料庫中有Book表,數據初始化類將返回,不添加任何數據。
// Look for any Books.
if (context.Book.Any())
{
return; // DB has been seeded
}
二、添加SeedData.initializer方法
1.在Visual Studio 2022 的解決方案資源管理器中打開Program.cs文件,然後找到Main方法,在這個方法體的最後面添加SeedData.Initialize()方法,代碼如下:
using BlazorAppDemo.Data;
using BlazorAppDemo.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
System.Console.WriteLine(ConfigHelper.Configuration["ConnectionStrings:BookContext"]);
builder.Services.AddDbContextFactory<BookContext>(opt =>
opt.UseSqlServer(ConfigHelper.Configuration["ConnectionStrings:BookContext"]));
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
//資料庫數據初始化
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
Console.WriteLine("資料庫開始初始化。");
var context = services.GetRequiredService<BookContext>();
// requires using Microsoft.EntityFrameworkCore;
context.Database.Migrate();
// Requires using BlazorAppDemo.Models;
SeedData.Initialize(services);
Console.WriteLine("資料庫初始化結束。");
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "資料庫數據初始化錯誤.");
}
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
2.在Visual Studio 2022中的菜單上選擇“生成-->開始調試”,或按F5鍵。運行BlazorAppDemo應用程式。如下圖。將進行資料庫初始化。
三、測試應用程式
1.在Visual Studio 2022中,打開“Pages\BookIndex.razor”文件,在此文件的頂部,輸入@inject IDbContextFactory<BookContext> dbFactory,註入資料庫上下文。
2.在@code中重寫OnInitializedAsync方法 ,在組件呈現時,去查詢資料庫中的Book表中的數據,最終呈現在頁面上。具體代碼如下。
@page "/BookIndex"
@using BlazorAppDemo.Models
@using Microsoft.EntityFrameworkCore
@inject IDbContextFactory<BookContext> dbFactory
<PageTitle>圖書列表</PageTitle>
<h3>圖書列表</h3>
<table class="table-responsive" width="90%">
<tr><td>Name</td>
<td>Author</td>
<td>Price</td>
<td>ReleaseDate</td>
<td>StockQty</td>
<td>Qty</td>
</tr>
@foreach (var item in books)
{
<tr>
<td>@item.Name</td>
<td>@item.Author</td>
<td>@item.Price</td>
<td>@item.ReleaseDate</td>
<td>@item.StockQty</td>
<td>@item.Qty</td>
</tr>
}
</table>
@code {
private static BookContext _context;
private List<Book> books = new List<Book>();
protected override async Task OnInitializedAsync()
{
_context = dbFactory.CreateDbContext();
books=_context.Book.ToList();
await base.OnInitializedAsync();
}
}
3. 在Visual Studio 2022中的菜單上選擇“生成à開始調試”,或按F5鍵。運行BlazorAppDemo應用程式。使用滑鼠右鍵點擊瀏覽器中左邊的菜單欄中的“圖書列表”菜單,在瀏覽器中顯示圖書信息。如下圖。