feat: DbContext

main
bicijinlian
parent db52c869ea
commit 57f6976efb

@ -19,7 +19,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
@ -31,7 +31,17 @@
"languageId": "polyglot-notebook"
}
},
"outputs": [],
"outputs": [
{
"data": {
"text/html": [
"<div><div><strong>Restore sources</strong><ul><li><span>https://api.nuget.org/v3/index.json</span></li></ul></div><div></div><div><strong>Installed Packages</strong><ul><li><span>Microsoft.EntityFrameworkCore, 7.0.5</span></li><li><span>Microsoft.EntityFrameworkCore.InMemory, 7.0.5</span></li><li><span>Microsoft.EntityFrameworkCore.Sqlite, 7.0.5</span></li><li><span>Microsoft.EntityFrameworkCore.SqlServer, 7.0.5</span></li></ul></div></div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"//设置包源\n",
"#i \"https://api.nuget.org/v3/index.json\"\n",
@ -50,6 +60,104 @@
"source": [
"## DbContext"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"outputs": [
{
"data": {
"text/html": [
"<table><thead><tr><th><i>index</i></th><th>value</th></tr></thead><tbody><tr><td>0</td><td><details class=\"dni-treeview\"><summary><span class=\"dni-code-hint\"><code>Submission#6+Account</code></span></summary><div><table><thead><tr></tr></thead><tbody><tr><td>Id</td><td><div class=\"dni-plaintext\"><pre>1</pre></div></td></tr><tr><td>Code</td><td>001</td></tr><tr><td>Name</td><td>zhangsan</td></tr><tr><td>Pwd</td><td>123456</td></tr><tr><td>Age</td><td><div class=\"dni-plaintext\"><pre>25</pre></div></td></tr><tr><td>State</td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr></tbody></table></div></details></td></tr><tr><td>1</td><td><details class=\"dni-treeview\"><summary><span class=\"dni-code-hint\"><code>Submission#6+Account</code></span></summary><div><table><thead><tr></tr></thead><tbody><tr><td>Id</td><td><div class=\"dni-plaintext\"><pre>2</pre></div></td></tr><tr><td>Code</td><td>002</td></tr><tr><td>Name</td><td>lisi</td></tr><tr><td>Pwd</td><td>123456</td></tr><tr><td>Age</td><td><div class=\"dni-plaintext\"><pre>35</pre></div></td></tr><tr><td>State</td><td><div class=\"dni-plaintext\"><pre>0</pre></div></td></tr></tbody></table></div></details></td></tr></tbody></table><style>\r\n",
".dni-code-hint {\r\n",
" font-style: italic;\r\n",
" overflow: hidden;\r\n",
" white-space: nowrap;\r\n",
"}\r\n",
".dni-treeview {\r\n",
" white-space: nowrap;\r\n",
"}\r\n",
".dni-treeview td {\r\n",
" vertical-align: top;\r\n",
" text-align: start;\r\n",
"}\r\n",
"details.dni-treeview {\r\n",
" padding-left: 1em;\r\n",
"}\r\n",
"table td {\r\n",
" text-align: start;\r\n",
"}\r\n",
"table tr { \r\n",
" vertical-align: top; \r\n",
" margin: 0em 0px;\r\n",
"}\r\n",
"table tr td pre \r\n",
"{ \r\n",
" vertical-align: top !important; \r\n",
" margin: 0em 0px !important;\r\n",
"} \r\n",
"table th {\r\n",
" text-align: start;\r\n",
"}\r\n",
"</style>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"using Microsoft.EntityFrameworkCore;\n",
"using Microsoft.EntityFrameworkCore.SqlServer;\n",
"public class AppDbContext: DbContext\n",
"{\n",
" public DbSet<Account> Accounts {get;set;}\n",
"\n",
" protected override void OnConfiguring(DbContextOptionsBuilder builder)\n",
" {\n",
" builder\n",
" .UseSqlServer(@\"Server=127.0.0.1\\SQL2019;Database=EFCore7Study;User Id=sa;Password=gly-bicijinlian;Encrypt=True;TrustServerCertificate=True;\")\n",
" .EnableSensitiveDataLogging();\n",
" }\n",
"\n",
" protected override void OnModelCreating(ModelBuilder builder)\n",
" {\n",
" builder.Entity<Account>().ToTable(\"Account\");\n",
" base.OnModelCreating(builder);\n",
" }\n",
"}\n",
"\n",
"public class Account\n",
"{\n",
" public int Id { get; set; }\n",
" public string Code { get; set; }\n",
" public string Name { get; set; }\n",
" public string Pwd { get; set; }\n",
"\n",
" public int Age { get; set; }\n",
"\n",
" public int State { get; set; } \n",
"}\n",
"\n",
"using(var db = new AppDbContext())\n",
"{\n",
" var itmes = db.Accounts.ToList();\n",
"\n",
" itmes.Display();\n",
"\n",
"}"
]
}
],
"metadata": {

@ -1,3 +1,60 @@
# 说明
========
EF Core 7的学习总结项目。
EF Core 7的学习总结项目。
## 使用 工厂对象(AddDbContextFactory)时,多构建函数时IoC获取对象时会异常
在使用扩展方法 AddDbContextFactory()注册服务时,如果 DbContext有多个构建函数会在获取服务时因为不知道使用哪个构建函数而异常。
解决方案:
+ 不要使用多构造函数
+ 合并成一个构建函数:比如统一使用 DbContextOptions<T> 参数非IoC可以手动构建 DbContextOptions<T> 对象当参数
+ 使用 ActivatorUtilitiesConstructor 特性指定IoC使用的构造函数
```csharp
public class AppDbContext : DbContext
{
private string? _connectString;
public AppDbContext()
{
}
public AppDbContext(string? connectstring, string dd = "dd")
{
_connectString = connectstring;
}
//指定IoC使用的构造函数
[ActivatorUtilitiesConstructor]
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
if (string.IsNullOrWhiteSpace(_connectString))
{
_connectString = @"Server=127.0.0.1\SQL2019;Database=EFCore7Study;User Id=sa;Password=xxxx;Encrypt=True;TrustServerCertificate=True;";
}
optionsBuilder
.UseSqlServer(_connectString)
.EnableSensitiveDataLogging();
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Account>().ToTable("Account");
base.OnModelCreating(modelBuilder);
}
public DbSet<Account> Accounts { get; set; }
}
```

@ -1,9 +1,37 @@
@page "/"
@using EFCore7Study.DataService;
@using EFCore7Study.DataService.Models;
@using Microsoft.EntityFrameworkCore;
@inject IDbContextFactory<AppDbContext> DbFactory
<PageTitle>Index</PageTitle>
@foreach(var account in AccountList)
{
<h2>@(account.Name)</h2>
}
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
@code{
private List<Account> AccountList { get; set; } = new List<Account>();
protected override void OnInitialized()
{
AccountList = GetAccounts();
base.OnInitialized();
}
private List<Account> GetAccounts()
{
using (var context = DbFactory.CreateDbContext())
{
return context.Accounts.ToList();
};
}
}

@ -1,7 +1,10 @@
using EFCore7Study.BlazorServerApp.Data;
using EFCore7Study.DataService;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
namespace EFCore7Study.BlazorServerApp
{
@ -16,6 +19,20 @@ namespace EFCore7Study.BlazorServerApp
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
//EF Core
var connectString = builder.Configuration.GetConnectionString("SQLServer");
builder.Services.AddDbContextFactory<AppDbContext>
(
b => b.UseSqlServer(connectString).EnableSensitiveDataLogging(), ServiceLifetime.Scoped
);
builder.Services.AddDbContextFactory<AppDbContext>(options => options.UseSqlServer(connectString));
var app = builder.Build();
// Configure the HTTP request pipeline.

@ -5,5 +5,8 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"ConnectionStrings": {
"SQLServer": "Server=127.0.0.1\\SQL2019;Database=EFCore7Study;User Id=sa;Password=gly-bicijinlian;Encrypt=True;TrustServerCertificate=True;"
}
}

@ -8,274 +8,53 @@ namespace EFCore7Study.CoreConsoleApp
{
static void Main(string[] args)
{
AnsiConsole.Status()
.Spinner(Spinner.Known.BouncingBar)
.Start("测试一个", ctx =>
{
ctx.Spinner(Spinner.Known.BouncingBar);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Aesthetic));
ctx.Spinner(Spinner.Known.Arc);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Arc));
ctx.Spinner(Spinner.Known.Arrow);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Arrow));
ctx.Spinner(Spinner.Known.Arrow2);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Arrow2));
ctx.Spinner(Spinner.Known.Arrow3);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Arrow3));
ctx.Spinner(Spinner.Known.Balloon);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Balloon));
ctx.Spinner(Spinner.Known.Balloon2);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Balloon2));
ctx.Spinner(Spinner.Known.BetaWave);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.BetaWave));
ctx.Spinner(Spinner.Known.Bounce);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Bounce));
ctx.Spinner(Spinner.Known.BouncingBall);
Thread.Sleep(3000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.BouncingBall));
ctx.Spinner(Spinner.Known.BouncingBar);
Thread.Sleep(3000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.BouncingBar));
ctx.Spinner(Spinner.Known.BoxBounce);
Thread.Sleep(3000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.BoxBounce));
ctx.Spinner(Spinner.Known.BoxBounce2);
Thread.Sleep(3000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.BoxBounce2));
ctx.Spinner(Spinner.Known.Dots8Bit);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Dots8Bit));
ctx.Spinner(Spinner.Known.Christmas);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Christmas));
ctx.Spinner(Spinner.Known.Circle);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Circle));
ctx.Spinner(Spinner.Known.CircleHalves);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.CircleHalves));
ctx.Spinner(Spinner.Known.CircleQuarters);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.CircleQuarters));
ctx.Spinner(Spinner.Known.Clock);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Clock));
ctx.Spinner(Spinner.Known.Default);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Default));
ctx.Spinner(Spinner.Known.Dots);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Dots));
ctx.Spinner(Spinner.Known.Dots2);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Dots2));
ctx.Spinner(Spinner.Known.Dots8Bit);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Dots8Bit));
//========================================================
ctx.Spinner(Spinner.Known.Dqpb);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Dqpb));
ctx.Spinner(Spinner.Known.Earth);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Earth));
ctx.Spinner(Spinner.Known.Flip);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Flip));
ctx.Spinner(Spinner.Known.Grenade);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Grenade));
ctx.Spinner(Spinner.Known.GrowHorizontal);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.GrowHorizontal));
ctx.Spinner(Spinner.Known.GrowVertical);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.GrowVertical));
ctx.Spinner(Spinner.Known.Hamburger);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Hamburger));
Thread.Sleep(2000);
ctx.Spinner(Spinner.Known.Hearts);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Hearts));
ctx.Spinner(Spinner.Known.Layer);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Layer));
ctx.Spinner(Spinner.Known.Line);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Line));
ctx.Spinner(Spinner.Known.Line2);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Line2));
ctx.Spinner(Spinner.Known.Material);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Material));
ctx.Spinner(Spinner.Known.Monkey);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Monkey));
ctx.Spinner(Spinner.Known.Moon);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Moon));
ctx.Spinner(Spinner.Known.Noise);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Noise));
ctx.Spinner(Spinner.Known.Pipe);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Pipe));
ctx.Spinner(Spinner.Known.Point);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Dots8Bit));
ctx.Spinner(Spinner.Known.Pong);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Pong));
ctx.Spinner(Spinner.Known.Runner);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Runner));
ctx.Spinner(Spinner.Known.Shark);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Shark));
ctx.Spinner(Spinner.Known.SimpleDots);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.SimpleDots));
ctx.Spinner(Spinner.Known.SimpleDotsScrolling);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.SimpleDotsScrolling));
ctx.Spinner(Spinner.Known.Smiley);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Smiley));
ctx.Spinner(Spinner.Known.SquareCorners);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.SquareCorners));
ctx.Spinner(Spinner.Known.Squish);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Squish));
ctx.Spinner(Spinner.Known.Star);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Star));
ctx.Spinner(Spinner.Known.Star2);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Star2));
ctx.Spinner(Spinner.Known.Toggle);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Toggle));
ctx.Spinner(Spinner.Known.Toggle2);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Toggle2));
ctx.Spinner(Spinner.Known.Triangle);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Triangle));
ctx.Spinner(Spinner.Known.Weather);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Weather));
ctx.Spinner(Spinner.Known.Weather);
Thread.Sleep(2000);
AnsiConsole.MarkupLine(nameof(Spinner.Known.Weather));
});
}
static void ShowQuery()
{
AnsiConsole.Status()
.Spinner(Spinner.Known.Balloon)
.Start("准备查询数据库...", ctx =>
{
Thread.Sleep(2000);
// 生成查询对象
ctx.Status("生成查询对象...");
AppDbContext dbContext = new AppDbContext();
Thread.Sleep(2000);
AnsiConsole.MarkupLine("生成查询对象: DbContext, 完成!");
// 连接数据库
ctx.Status("正在连接到数据库服务器...");
ctx.Spinner(Spinner.Known.Balloon);
ctx.SpinnerStyle(Style.Parse("green"));
Thread.Sleep(2000);
AnsiConsole.MarkupLine("已连接到数据库服务器!");
// 查询数据
ctx.Status("正在查询数据...");
ctx.Spinner(Spinner.Known.Star2);
ctx.SpinnerStyle(Style.Parse("yellow"));
Thread.Sleep(3000);
AnsiConsole.MarkupLine("完成查询!");
//输出查询结果
ctx.Status("输出查询结果...");
ctx.Spinner(Spinner.Known.Arrow);
ctx.SpinnerStyle(Style.Parse("red"));
dbContext.Accounts.ToList().ForEach(x =>
{
AnsiConsole.MarkupLine($"标识:{x.Id},编号:{x.Code}, 姓名:{x.Name.PadRight(10)},年龄:{x.Age}, 密码:{x.Pwd}");
Thread.Sleep(300);
});
AnsiConsole.MarkupLine("任务完成!");
});
.Spinner(Spinner.Known.Balloon)
.Start("准备查询数据库...", ctx =>
{
Thread.Sleep(2000);
// 生成查询对象
ctx.Status("生成查询对象...");
AppDbContext dbContext = new AppDbContext();
//Thread.Sleep(2000);
AnsiConsole.MarkupLine("生成查询对象: DbContext, 完成!");
// 连接数据库
ctx.Status("正在连接到数据库服务器...");
ctx.Spinner(Spinner.Known.Balloon);
ctx.SpinnerStyle(Style.Parse("green"));
//Thread.Sleep(2000);
AnsiConsole.MarkupLine("已连接到数据库服务器!");
// 查询数据
ctx.Status("正在查询数据...");
ctx.Spinner(Spinner.Known.Star2);
ctx.SpinnerStyle(Style.Parse("yellow"));
//Thread.Sleep(3000);
AnsiConsole.MarkupLine("完成查询!");
//输出查询结果
ctx.Status("输出查询结果...");
ctx.Spinner(Spinner.Known.Arrow);
ctx.SpinnerStyle(Style.Parse("red"));
dbContext.Accounts.ToList().ForEach(x =>
{
AnsiConsole.MarkupLine($"标识:{x.Id},编号:{x.Code}, 姓名:{x.Name.PadRight(10)},年龄:{x.Age}, 密码:{x.Pwd}");
Thread.Sleep(300);
});
AnsiConsole.MarkupLine("任务完成!");
});
}
}
}

@ -1,25 +1,27 @@
using EFCore7Study.DataService.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace EFCore7Study.DataService
{
/// <summary>
/// 多构造函数
/// 为使用工厂方式注册,加 ActivatorUtilitiesConstructor 特性
/// </summary>
public class AppDbContext : DbContext
{
private string? _connectString;
/// <summary>
/// 连接字符串可实现属性设置避免多构造函数在Factory时IoC异常
/// </summary>
public string? ConnectString = @"Server=127.0.0.1\SQL2019;Database=EFCore7Study;User Id=sa;Password=gly-bicijinlian;Encrypt=True;TrustServerCertificate=True;";
public AppDbContext()
{
}
public AppDbContext(string connectstring)
{
_connectString = connectstring;
}
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
@ -28,13 +30,13 @@ namespace EFCore7Study.DataService
{
if (!optionsBuilder.IsConfigured)
{
if (string.IsNullOrWhiteSpace(_connectString))
if (string.IsNullOrWhiteSpace(ConnectString))
{
_connectString = @"Server=127.0.0.1\SQL2019;Database=EFCore7Study;User Id=sa;Password=gly-bicijinlian;Encrypt=True;TrustServerCertificate=True;";
ConnectString = @"Server=127.0.0.1\SQL2019;Database=EFCore7Study;User Id=sa;Password=gly-bicijinlian;Encrypt=True;TrustServerCertificate=True;";
}
optionsBuilder
.UseSqlServer(_connectString)
.UseSqlServer(ConnectString)
.EnableSensitiveDataLogging();
}
}

@ -0,0 +1,49 @@
using EFCore7Study.DataService.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure.Internal;
using Microsoft.Extensions.DependencyInjection;
namespace EFCore7Study.DataService
{
/// <summary>
/// 多构造函数
/// 为使用工厂方式注册,合并为一个
/// </summary>
public class AppDbContext2 : DbContext
{
private string? _connectString;
//因为先执行的 base(options),到此处时AppDbContext2已经注册完成连接字符串实际上是用不了的。当然换成其它参数或用在其它地方是可以的。
public AppDbContext2(DbContextOptions<AppDbContext2> options, string? connectString = null)
: base(options)
{
_connectString = connectString;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
if (string.IsNullOrWhiteSpace(_connectString))
{
_connectString = @"Server=127.0.0.1\SQL2019;Database=EFCore7Study;User Id=sa;Password=gly-bicijinlian;Encrypt=True;TrustServerCertificate=True;";
}
optionsBuilder
.UseSqlServer(_connectString)
.EnableSensitiveDataLogging();
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Account>().ToTable("Account");
base.OnModelCreating(modelBuilder);
}
public DbSet<Account> Accounts { get; set; }
}
}

@ -0,0 +1,58 @@
using EFCore7Study.DataService.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace EFCore7Study.DataService
{
/// <summary>
/// 多构造函数
/// 使用工厂对象(AddDbContextFactory)时,因多构建函数IoC 获取对象时会异常
/// </summary>
public class AppDbContext3 : DbContext
{
private string? _connectString;
public AppDbContext3()
{
}
public AppDbContext3(string? connectstring)
{
_connectString = connectstring;
}
public AppDbContext3(DbContextOptions<AppDbContext> options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
if (string.IsNullOrWhiteSpace(_connectString))
{
_connectString = @"Server=127.0.0.1\SQL2019;Database=EFCore7Study;User Id=sa;Password=gly-bicijinlian;Encrypt=True;TrustServerCertificate=True;";
}
optionsBuilder
.UseSqlServer(_connectString)
.EnableSensitiveDataLogging();
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Account>().ToTable("Account");
base.OnModelCreating(modelBuilder);
}
public DbSet<Account> Accounts { get; set; }
}
}

@ -6,9 +6,9 @@
public class Account
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string Pwd { get; set; }
public string Code { get; set; } = "";
public string Name { get; set; } = "";
public string Pwd { get; set; } = "";
public int Age { get; set; }

@ -0,0 +1,26 @@
using EFCore7Study.DataService;
using EFCore7Study.DataService.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace EFCore7Study.WebApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class AccountsController : ControllerBase
{
private readonly AppDbContext _dbContext;
public AccountsController(AppDbContext context)
{
_dbContext = context;
}
[HttpGet]
public List<Account> AllAccounts()
{
return _dbContext.Accounts.ToList();
}
}
}

@ -0,0 +1,43 @@
using EFCore7Study.DataService;
using EFCore7Study.DataService.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
namespace EFCore7Study.WebApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class EFCore2Controller : ControllerBase
{
private readonly AppDbContext2 _context;
private readonly IDbContextFactory<AppDbContext2> _factory;
public EFCore2Controller
(
AppDbContext2 context,
IDbContextFactory<AppDbContext2> factory
)
{
_context = context;
_factory = factory;
}
[HttpGet]
public List<Account> GetAll()
{
return _context.Accounts.AsNoTracking().ToList();
}
[HttpGet]
public List<Account> GetAllByFactory()
{
using (var db = _factory.CreateDbContext())
{
return db.Accounts.AsNoTracking().ToList();
}
}
}
}

@ -0,0 +1,60 @@
using EFCore7Study.DataService;
using EFCore7Study.DataService.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
namespace EFCore7Study.WebApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class EFCore3Controller : ControllerBase
{
private readonly IDbContextFactory<AppDbContext3> _contextFactory;
public EFCore3Controller(IDbContextFactory<AppDbContext3> contextFactory)
{
_contextFactory = contextFactory;
}
[HttpGet]
public List<Account> GetAll()
{
return _contextFactory.CreateDbContext().Accounts.ToList();
}
[HttpGet]
public List<Account> GetAll2()
{
return _contextFactory.CreateDbContext().Accounts.ToList();
}
[HttpGet]
public List<Account> GetAll3()
{
return _contextFactory.CreateDbContext().Accounts.ToList();
}
[HttpGet]
public List<Account> GetAll4()
{
return _contextFactory.CreateDbContext().Accounts.ToList();
}
[HttpGet]
public List<Account> GetAll5()
{
return _contextFactory.CreateDbContext().Accounts.ToList();
}
[HttpGet]
public List<Account> GetAll6()
{
return _contextFactory.CreateDbContext().Accounts.ToList();
}
}
}

@ -0,0 +1,63 @@
using EFCore7Study.DataService;
using EFCore7Study.DataService.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace EFCore7Study.WebApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class EFCoreController : ControllerBase
{
private readonly AppDbContext _connect;
private readonly IDbContextFactory<AppDbContext> _factory;
public EFCoreController(AppDbContext context, IDbContextFactory<AppDbContext> factory)
{
_connect = context;
_factory = factory;
}
[HttpGet]
public List<Account> GetAll()
{
return _connect.Accounts.ToList();
}
[HttpGet]
public List<Account> GetAllByFactory()
{
using (var db = _factory.CreateDbContext())
{
return db.Accounts.ToList();
}
}
[HttpGet]
public List<Account> GetAll3()
{
return _connect.Accounts.ToList();
}
[HttpGet]
public List<Account> GetAll4()
{
return _connect.Accounts.ToList();
}
[HttpGet]
public List<Account> GetAll5()
{
return _connect.Accounts.ToList();
}
[HttpGet]
public List<Account> GetAll6()
{
return _connect.Accounts.ToList();
}
}
}

@ -12,4 +12,8 @@
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EFCore7Study.DataService\EFCore7Study.DataService.csproj" />
</ItemGroup>
</Project>

@ -1,3 +1,7 @@
using EFCore7Study.DataService;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.SqlServer;
namespace EFCore7Study.WebApi
{
@ -14,9 +18,132 @@ namespace EFCore7Study.WebApi
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
//注册服务EFCore
#region 注册服务EFCore
var connectString = builder.Configuration.GetConnectionString("SQLServer");
var contextOptionsBuilder = new DbContextOptionsBuilder<AppDbContext>()
.UseSqlServer(connectString)
.EnableSensitiveDataLogging();
var contextOptions = contextOptionsBuilder.Options;
//方式一:默认构造,使用内部数据连接
//builder.Services.AddScoped(provider => new AppDbContext());
//方式二: 设置连接字符串属性
//builder.Services.AddScoped(provider =>
//{
// var db = new AppDbContext();
// db.ConnectString = connectString;
// return db;
//});
//方法三:使用 DbContextOptions 的构建函数 [比较推荐]
//builder.Services.AddScoped<AppDbContext>(provider => new AppDbContext(contextOptions));
//方式四:使用 AddDbContext 扩展方法 [官方推荐]
//小问题:会覆盖之前方法的服务注册,猜测内部进行过去重复处理过,要验证请使用 GetServices 获取所有注册的服务。
//解决:方法三放在方法四后面
//builder.Services.AddDbContext<AppDbContext>(option =>
//{
// //从配置中获取连接字符串
// option.UseSqlServer(connectString)
// .EnableSensitiveDataLogging();
//});
//方式五: 使用 DbContextFactory 工厂
//注意:
// 1、此方法与方法四都是注册的 AppDbContext对象方法四默认为Scoped,此方式默认为单例,两者的冲突导致异常
// 2、此方法与方法四都会覆盖之前的 AppDbContext 注册
//解决:
// 1、此方法不与方法4同用如果要同时使用请使用方法1-3
// 2、使此方法与方法四应用相同生命周期
//builder.Services.AddDbContextFactory<AppDbContext>(optionBuilder =>
//{
// optionBuilder.UseSqlServer(connectString)
// .EnableSensitiveDataLogging();
//});
//使用自定的覆盖工厂的AppDbContext,但工厂本身的IDbContextFactory<AppDbContext>不会覆盖,可以分开使用。
//builder.Services.AddScoped<AppDbContext>(provider => new AppDbContext(contextOptions));
//方式六:使用 DbContextPool 池
builder.Services.AddDbContextPool<AppDbContext>((provider, optionBuilder) =>
{
//provider.GetRequiredService<AppDbContext>();
optionBuilder.UseSqlServer(connectString)
.EnableSensitiveDataLogging();
}, poolSize: 2048);
//方式七:使用连接池的工厂
builder.Services.AddPooledDbContextFactory<AppDbContext>((serviceProvider, optionBuilder) =>
{
//serviceProvider.GetRequiredService<AppDbContext>();
optionBuilder.UseSqlServer(connectString)
.EnableSensitiveDataLogging();
}, poolSize: 1024);
//使用自定的覆盖工厂的AppDbContext,但工厂本身的IDbContextFactory<AppDbContext>不会覆盖,可以分开使用。
builder.Services.AddScoped(provider => new AppDbContext());
//获取所有注册的服务(可没查看是否覆盖注册)
//var dd = builder?.Services?.BuildServiceProvider().GetServices<AppDbContext>();
#endregion
#region 注册服务EFCore2
var contextOptionBuilder2 = new DbContextOptionsBuilder<AppDbContext2>()
.UseSqlServer(connectString)
.EnableSensitiveDataLogging();
DbContextOptions<AppDbContext2>? contextOptions2 = contextOptionBuilder2.Options;
//方法:使用 统一构建函数
//builder.Services.AddScoped<AppDbContext2>(provider => new AppDbContext2(contextOptions));
//或者
builder?.Services.AddScoped(provider => new AppDbContext2(contextOptions2, connectString));
//方式:使用 AddDbContext 扩展方法 [官方推荐]
//builder.Services.AddDbContext<AppDbContext2>((server, option) =>
//{
// //从配置中获取连接字符串
// //builder.Configuration.GetConnectionString("SQLServer");
// //设置
// option.UseSqlServer(connectString)
// .EnableSensitiveDataLogging();
//});
//方式: 使用 DbContextFactory 工厂
//builder.Services.AddDbContextFactory<AppDbContext2>(optionBuilder =>
//{
// optionBuilder.UseSqlServer(connectString)
// .EnableSensitiveDataLogging();
//}, ServiceLifetime.Scoped);
//或者
//builder.Services.AddDbContextFactory<AppDbContext2>((provider, builder) =>
//{
//}, ServiceLifetime.Scoped);
//方式:使用 DbContextPool 池
//builder.Services.AddDbContextPool<AppDbContext2>(optionBuilder =>
//{
// optionBuilder.UseSqlServer(connectString)
// .EnableSensitiveDataLogging();
//});
//方式:使用连接池的工厂
//builder.Services.AddPooledDbContextFactory<AppDbContext2>(optionBuilder =>
//{
// optionBuilder.UseSqlServer(connectString)
// .EnableSensitiveDataLogging();
//});
#endregion
var app = builder!.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();

@ -5,5 +5,8 @@
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
"AllowedHosts": "*",
"ConnectionStrings": {
"SQLServer": "Server=127.0.0.1\\SQL2019;Database=EFCore7Study;User Id=sa;Password=gly-bicijinlian;Encrypt=True;TrustServerCertificate=True;"
}
}

Loading…
Cancel
Save