目录
前文已经说过.NET Framework4.8 控制台应用通过EF访问已经建立的和新建的数据库。
前文已经说过.NET 6.0 控制台应用通过EF访问已经建立的数据库。
本文想说的是,.NET 7.0 Windows窗体应用通过EF访问新建数据库,这里的数据据库要根据事先编写好的EF模型、和数据库上下文,经过一番操作,移植(Migrations)出来的。这个数据库在“工具、连接到数据库”是看不到这个数据库的连接的。【本文涉及道德方法同样适用于.NET 6.0 Windows窗体应用】
步骤1和步骤2作者以前的文章都讲过,不再重复叙述。
添加→新建项目→类,复制粘贴以下全文,一定要保证所有.cs文件在同一片空间下(namespace)。
- //编写EF实体模型和数据库上下文
- using Microsoft.EntityFrameworkCore;
-
- namespace _10_15
- {
- public class BloggingContext : DbContext
- {
- public DbSet
? Blogs { get; set; } - public DbSet
? Posts { get; set; } -
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;");
- }
- }
-
- public class Blog
- {
- public int? BlogId { get; set; }
- public string? Url { get; set; }
-
- public List
? Posts { get; set; } - }
-
- public class Post
- {
- public int? PostId { get; set; }
- public string? Title { get; set; }
- public string? Content { get; set; }
-
- public int? BlogId { get; set; }
- public Blog? Blog { get; set; }
- }
- }
- //移植并新建数据库
- PM> Import-Module C:\Users\YCZN_MT\.nuget\packages\microsoft.entityframeworkcore.tools\7.0.14\tools\EntityFrameworkCore.psd1
- 模块“EntityFrameworkCore”中的某些导入命令的名称包含未批准的动词,这些动词可能导致这些命令名不易被发现。若要查找具有未批准的动词的命令,请使用 Verbose 参数再次运行 Import-Module 命令。有关批准的动词列表,请键入 Get-Verb。
- PM> Get-Verb
-
- Verb Group
- ---- -----
- Add Common
- Clear Common
- Close Common
- Copy Common
- Enter Common
- Exit Common
- Find Common
- Format Common
- Get Common
- Hide Common
- Join Common
- Lock Common
- Move Common
- New Common
- Open Common
- Optimize Common
- Pop Common
- Push Common
- Redo Common
- Remove Common
- Rename Common
- Reset Common
- Resize Common
- Search Common
- Select Common
- Set Common
- Show Common
- Skip Common
- Split Common
- Step Common
- Switch Common
- Undo Common
- Unlock Common
- Watch Common
- Backup Data
- Checkpoint Data
- Compare Data
- Compress Data
- Convert Data
- ConvertFrom Data
- ConvertTo Data
- Dismount Data
- Edit Data
- Expand Data
- Export Data
- Group Data
- Import Data
- Initialize Data
- Limit Data
- Merge Data
- Mount Data
- Out Data
- Publish Data
- Restore Data
- Save Data
- Sync Data
- Unpublish Data
- Update Data
- Approve Lifecycle
- Assert Lifecycle
- Complete Lifecycle
- Confirm Lifecycle
- Deny Lifecycle
- Disable Lifecycle
- Enable Lifecycle
- Install Lifecycle
- Invoke Lifecycle
- Register Lifecycle
- Request Lifecycle
- Restart Lifecycle
- Resume Lifecycle
- Start Lifecycle
- Stop Lifecycle
- Submit Lifecycle
- Suspend Lifecycle
- Uninstall Lifecycle
- Unregister Lifecycle
- Wait Lifecycle
- Debug Diagnostic
- Measure Diagnostic
- Ping Diagnostic
- Repair Diagnostic
- Resolve Diagnostic
- Test Diagnostic
- Trace Diagnostic
- Connect Communications
- Disconnect Communications
- Read Communications
- Receive Communications
- Send Communications
- Write Communications
- Block Security
- Grant Security
- Protect Security
- Revoke Security
- Unblock Security
- Unprotect Security
- Use Other
-
-
- PM> Add-Migration
- 位于命令管道位置 1 的 cmdlet Add-Migration
- 请为以下参数提供值:
- Name: MyMigration
- Build started...
- Build succeeded.
- To undo this action, use Remove-Migration.
- PM> Update-Database
- Build started...
- Build succeeded.
- Applying migration '20231115072504_MyMigration'.
- Failed executing DbCommand (3ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
- CREATE TABLE [Blogs] (
- [BlogId] int NOT NULL IDENTITY,
- [Url] nvarchar(max) NOT NULL,
- CONSTRAINT [PK_Blogs] PRIMARY KEY ([BlogId])
- );
- Microsoft.Data.SqlClient.SqlException (0x80131904): There is already an object named 'Blogs' in the database.
- at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
- at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
- at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
- at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
- at Microsoft.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean isAsync, Int32 timeout, Boolean asyncWrite)
- at Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String methodName)
- at Microsoft.Data.SqlClient.SqlCommand.ExecuteNonQuery()
- at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
- at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
- at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IEnumerable`1 migrationCommands, IRelationalConnection connection)
- at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
- at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType)
- at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
- at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
- at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
- ClientConnectionId:9c23d064-4612-470a-873c-665d7d583836
- Error Number:2714,State:6,Class:16
- There is already an object named 'Blogs' in the database.
- PM>
我的电脑中在其他项目中已经移植生成过同样的数据库,因此在数据库更新时提示并警告,忽略就好了,不影响本项目的调试和运行的。
- // .NET 7.0窗体应用访问新建数据库
- // 对数据库进行追加记录、删除记录操作
-
- namespace _10_15
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
-
- ///
- /// 初始化Form1
- /// 初始化表格,显示数据表
- ///
- private void Form1_Load(object sender, EventArgs e)
- {
- button1.Text = "追加";
- button2.Text = "删除";
- label1.Text = "追加的Url:";
- label2.Text = "删除的ID:";
-
- button1.Size = new Size(40, 23);
- button2.Size = new Size(40, 23);
-
- dataGridView1.AllowUserToAddRows = false;
- dataGridView1.AllowUserToDeleteRows = false;
- dataGridView1.AllowUserToResizeColumns = false;
- dataGridView1.AllowUserToResizeRows = false;
- dataGridView1.RowHeadersVisible = false;
- dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
-
- using var db = new BloggingContext();
- dataGridView1.DataSource = db.Blogs?.ToList();
- }
-
- ///
- /// 追加Add()
- /// 无论ID是否连续,都在数据库末尾追加新纪录
- ///
- private void Button1_Click(object sender, EventArgs e)
- {
- using var db = new BloggingContext();
- if (textBox1.Text != "")
- {
- db.Blogs?.Add(new Blog { Url = textBox1.Text.Trim().ToString() }); //追加记录
- db.SaveChanges();
- dataGridView1.DataSource = db.Blogs?.ToList();
- }
- else
- {
- db.Blogs?.Add(new Blog { Url = "http://www.hao123.com/" }); //追加记录
- db.SaveChanges();
- dataGridView1.DataSource = db.Blogs?.ToList();
- }
- }
-
- ///
- /// 删除Remove()
- ///
- private void Button2_Click(object sender, EventArgs e)
- {
- using var db = new BloggingContext();
- db.Blogs?.Remove(new Blog { BlogId = Convert.ToInt32(textBox2.Text.Trim()) }); //删除记录按ID
- db.SaveChanges();
- dataGridView1.DataSource = db.Blogs?.ToList();
- }
- }
- }

追加:http://news.sina.com.cn/
删除:ID=3的记录