C#中.NET 7.0 Windows窗体应用通过EF访问已有数据库并实现追加、删除、修改、插入记录

目录

一、前言

1.Database.ExecuteSqlCommand 方法不被EF7.0支持

2.SET IDENTITY_INSERT Blog {ON,OFF}不起作用

3.主键和标识列分离,成功实现插入与修改

二、新建本文涉及的项目

三、程序设计

1.Form1.cs源码

2.Form1.cs[设计]

四、生成和测试

1.原始表

2.空内容追加

3.有内容追加、删除记录ID=2、插入记录ID=3

4.插入记录ID=33

5.修改记录ID=31

五、后记


一、前言

        在发布这篇文章之前,先说一下作者为了实现通过EF修改已有数据库记录和在任意空位置插入数据库记录所做过的一些尝试,做这些尝试很累甚至一度失望。因为EF已经更新到7.0(刚刚又更新到了8.0),EF7相对于EF6之前的版本有了一些改变,甚至放弃了一些不安全的对数据库操作的函数,缺少经验的人在知道到的情况下,继续使用那些在EF7以后得版本不再支持的函数,找不到原因的时候是很崩溃的。现在总结一下在写本文时遭遇的EF6函数不再被EF7支持的“花絮”。

        我的环境:VS2022,Windows窗体应用,.NET 7.0,NuGet程序包:microsoft.entityframeworkcore.7.0.14、microsoft.entityframeworkcore.design.7.0.14、microsoft.entityframeworkcore.relational.7.0.14、microsoft.entityframeworkcore.sqlserver.7.0.14、microsoft.entityframeworkcore.tools.7.0.14。

        数据库:Blogging 。

1.Database.ExecuteSqlCommand 方法不被EF7.0支持

严重性

代码

说明

项目

文件

禁止显示状态

错误

CS1061

“DatabaseFacade”未包含“ExecuteSqlCommand”的定义,并且找不到可接受第一个“DatabaseFacade”类型参数的可访问扩展方法“ExecuteSqlCommand”(是否缺少 using 指令或程序集引用?)

10_10

C:\Users\YCZN_MT\Desktop\10_10\10_10\Form1.cs

71

活动

         在db.db.Database.后面的方法里根本就找不到ExecuteSqlCommand()了。

2.SET IDENTITY_INSERT Blog {ON,OFF}不起作用

        db.Database.ExecuteSql($"SET IDENTITY_INSERT Blog ON")

        对数据库记录的写入操作

        db.Database.ExecuteSql($"SET IDENTITY_INSERT Blog OFF")

         以上组合根本就不起作用,网络上的  db.Database.ExecuteSqlCommand ()因为不被支持,所以换上 db.Database.ExecuteSql(),在 db2.SaveChanges()处就停下来了,根本就不能将数据写入数据库。无法改变标识列的开与关。

        提示“当 IDENTITY_INSERT 设置为 OFF 时,不能向表 ' Blog' 中的标识列插入显式值。”

3.主键和标识列分离,成功实现插入与修改

         当主键和IDENTITY列是同一列时,由于EF7废弃了Database.ExecuteSqlCommand ()方法,致使无法在C#中编程实现对SET IDENTITY_INSERT Blog ON或OFF。SQL里的标识列始终起作用,SQL不接受插入不存在记录和修改数据已有记录。

        采用主键和IDENTITY列分离,新增加一个列作为标识列,起辅助作用,用途只为了实现插入和修改记录。

        采用主键和IDENTITY列分离后,依赖原来的IDENTITY列的追加功能,需要用编程的方法,对BlogId字段进行赋值,本文采用的复制算法是:BlogId=InsertId-1,即BlogId始终等于上一条记录的IDENTITY值。

        下面发布正文:

二、新建本文涉及的项目

         由于作者前期的文章关于这一步都有涉及,因此,此处只写过程的操作摘要:

         VS2022,新建Windows窗体应用,.NET 7.0,NuGet程序包版本7.0.14→工具、连接到数据库,Blogging → 逆向工程,生成EF实体模型及数据库上下文→设计Form1.cs[设计]和Form1.cs→生成测试。

        其中:PM> Scaffold-DbContext "Server=DESKTOP-3LV13FS;Database=Blogging;Trusted_Connection=True;TrustServerCertificate=true;integrated security=SSPI;" Microsoft.EntityFrameworkCore.SqlServer

        数据库更新时:PM> Scaffold-DbContext- -Force "Server=DESKTOP-3LV13FS;Database=Blogging;Trusted_Connection=True;TrustServerCertificate=true;integrated security=SSPI;" Microsoft.EntityFrameworkCore.SqlServer

三、程序设计

1.Form1.cs源码

//Form1.cs
//EF7对已有数据库增加、删除、修改、插入
using System.Data;

namespace _10_10
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 初始化Form1
        /// 初始化表格,显示数据表
        /// </summary>
        #region Form1_Load
        private void Form1_Load(object sender, EventArgs e)
        {
            button1.Text = "追加";
            button2.Text = "删除";
            button3.Text = "插入/覆盖";
            label1.Text = "追加的Url:";
            label2.Text = "删除的ID:";
            label3.Text = "插入记录:";

            button1.Size = new Size(40, 23);
            button2.Size = new Size(40, 23);
            textBox2.Size = new Size(30, 23);
            textBox3.Size = new Size(30, 23);
            textBox4.Size = new Size(125, 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();
        }
        #endregion Form1_Load

        /// <summary>
        /// 追加Add()
        /// 无论ID是否连续,都在数据库末尾追加新纪录
        /// </summary>
        #region 追加记录
        private void Button1_Click(object sender, EventArgs e)
        {
            int _rows = dataGridView1.Rows.Count;
            using var db = new BloggingContext();
            if (textBox1.Text != "")
            {               
                var table = new Blog
                {
                    BlogId = Convert.ToInt32(dataGridView1.Rows[_rows - 1].Cells[2].Value.ToString()),
                    Url = textBox1.Text.Trim().ToString()
                };
                db.Blogs.Add(table); //追加记录
                db.SaveChanges();
                dataGridView1.DataSource = db.Blogs.ToList();
            }
            else
            {
                var table = new Blog
                {
                    BlogId = Convert.ToInt32(dataGridView1.Rows[_rows-1].Cells[2].Value.ToString()),
                    Url = "http://www.hao123.com/"
                }; 
                db.Blogs.Add(table);//追加记录
                db.SaveChanges();
                dataGridView1.DataSource = db.Blogs.ToList();
            }
        }
        #endregion 追加记录
        
        /// <summary>
        /// 删除Remove()
        /// </summary>
        #region 删除记录
        private void Button2_Click(object sender, EventArgs e)
        {
            if (textBox2.Text != string.Empty)
            {
                using var db = new BloggingContext();
                var data = (from tb in db.Blogs where tb.BlogId == Convert.ToInt32(textBox2.Text.Trim()) 
                            select tb).FirstOrDefault();    //判断数据表中是否包含要删除的ID
                if (data != null)
                {
                    using var db2 = new BloggingContext();
                    var tableNew = new Blog
                    {
                        BlogId = Convert.ToInt32(textBox2.Text.Trim())
                    };
                    db2.Blogs.Remove(tableNew);     //删除记录按ID
                    db2.SaveChanges();
                    dataGridView1.DataSource = db2.Blogs.ToList();
                }
                else
                {
                    MessageBox.Show("数据表中没有这个ID,请重新输入", "提示");
                }
            }
            else
            {
                MessageBox.Show("请输入要删除记录的编号", "提示");
            }
        }
        #endregion 删除记录

        /// <summary>
        /// 插入或覆盖
        /// 要插入的ID存在则覆盖原纪录;
        /// 要插入的ID不存在则添加记录;
        /// Linq无法直接更新主键的数据,只能是先将此条信息复制出来,把原来的那条数据删除,
        /// 再重新插入一条修改后的数据,若不是主键数据,则直接更新
        /// </summary>
        #region 插入或覆盖记录
        private void Button3_Click(object sender, EventArgs e)
        {
            
            if (textBox3.Text.Trim() == string.Empty)
            {
                MessageBox.Show("ID不能为空,请重新输入","提示");
            }
            else
            {
                using var db = new BloggingContext();
                //db.Database.ExecuteSql($"SET IDENTITY_INSERT Blog ON");  
                var data = (from tb in db.Blogs
                            where tb.BlogId == Convert.ToInt32(textBox3.Text.Trim())
                            select tb).FirstOrDefault();//判断数据表中是否包含要插入的ID
                if (data != null)
                {
                    using var db2 = new BloggingContext();
                    //db2.Database.ExecuteSql($"SET IDENTITY_INSERT Blog ON");
                    var tableNew = new Blog
                    {
                        BlogId = Convert.ToInt32(textBox3.Text.Trim()),
                        Url = textBox4.Text.Trim().ToString()
                    };                   
                    db2.Blogs.Remove(data);       //移除老数据                    
                    db2.Blogs.Add(tableNew);     //添加新数据
                    db2.SaveChanges();              //执行更新操作
                    //db2.Database.ExecuteSql($"SET IDENTITY_INSERT Blog OFF");
                    dataGridView1.DataSource = db2.Blogs.ToList();
                }
                else
                {
                    using var db2 = new BloggingContext();
                    //db2.Database.ExecuteSql($"SET IDENTITY_INSERT Blog ON");
                    var table = new Blog
                    {
                        BlogId = Convert.ToInt32(textBox3.Text.Trim()),
                        Url = textBox4.Text.Trim().ToString()
                    };
                    db2.Blogs.Add(table);        //执行插入操作
                    db2.SaveChanges();
                    //db2.Database.ExecuteSql($"SET IDENTITY_INSERT Blog OFF");
                    dataGridView1.DataSource = db2.Blogs.ToList();
                }
                //db.Database.ExecuteSql($"SET IDENTITY_INSERT Blog OFF");
            }            
        }
        #endregion 插入或覆盖记录
    }
}

2.Form1.cs[设计]

 

四、生成和测试

1.原始表

2.空内容追加

 

3.有内容追加、删除记录ID=2、插入记录ID=3

4.插入记录ID=33

5.修改记录ID=31

五、后记

        本文所使用的主键和标识列分离的方法实现对数据库已有记录的修改,不存在的记录的插入操作,仅代表作者的一种实现方法,不代表是唯一的实现方法。也许读者们有更好的实现办法。希望在日后的工作中此方面能与读者共勉共研。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/167533.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【EI会议征稿】2024年电气技术与自动化工程国际学术会议 (ETAE 2024)

2024年电气技术与自动化工程国际学术会议 (ETAE 2024) 2024 International Conference on Electrical Technology and Automation Engineering 2024年电气技术与自动化工程国际学术会议 (ETAE 2024) 将于2024年3月8-10日在中国杭州召开。电气工程及其自动化和人们的日常生活…

Vue3的7种和Vue2的12种组件通信

Vue3 组件通信方式 props$emitexpose / ref$attrsv-modelprovide / injectVuex Vue3 通信使用写法 props 用 props 传数据给子组件有两种方法&#xff0c;如下 方法一&#xff0c;混合写法 // Parent.vue 传送 <child :msg1"msg1" :msg2"msg2">…

CLIP浅谈

CLIP论文地址&#xff1a;Learning Transferable Visual Models From Natural Language Supervision CLIP代码地址&#xff1a;https://github.com/openai/CLIP 简介 CLIP是OpenAI在2021年2月发表的一篇文章&#xff0c;它的主要贡献有以下2点&#xff1a; 1&#xff09;将图…

MCU内存基础知识

文章目录 一、存储器分类二、C语言内存分区内存区三、STM32启动文件分析四、应用分析 一、存储器分类 RAM&#xff08;Random Access Memory) &#xff1a;掉电之后就丢失数据&#xff0c;读写速度块 ROM (Read Only Memory) &#xff1a;掉电之后仍然可以保持数据 单片机的RA…

【Java SE】 详解java访问限定符

访问限定符 Java中主要通过类和访问权限来实现封装&#xff1a;类可以将数据以及封装数据的方法结合在一起&#xff0c;更符合人类对事物的认知&#xff0c;而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符&#xff1a; 实际只有三种访问限定…

纯CSS动态渐变文本特效

如图所示&#xff0c;这是一个炫酷的文本渐变效果&#xff0c;如同冰岛的极光一般。本次的文章让我们逐步分解代码&#xff0c;了解其实现原理。 基于以上动图效果可以分析以下是本次动效实现的主要几点&#xff1a; 文本中有多个颜色的动画每个颜色显示的半径不同&#xff0…

亚马逊化妆品护肤品等HRIPT/RIPT重复性斑贴测试如何办理?

一、哪类产品需要HRIPT / RIPT斑贴试验&#xff1a; HRIPT&#xff08;人体重复斑点试验&#xff09;和RIPT&#xff08;人体斑点试验&#xff09;是化妆品相关的测试&#xff0c;用于评估化妆品是否可能引起皮肤敏感和过敏反应。只有化妆品类产品需要进行HRIPT / RIPT斑贴试验…

五分钟搭建开源ERP:Odoo,并实现公网远程访问

文章目录 前言1. 下载安装Odoo&#xff1a;2. 实现公网访问Odoo本地系统&#xff1a;3. 固定域名访问Odoo本地系统 前言 Odoo是全球流行的开源企业管理套件&#xff0c;是一个一站式全功能ERP及电商平台。 开源性质&#xff1a;Odoo是一个开源的ERP软件&#xff0c;这意味着企…

普通函数VS箭头函数

首先给大家看一个代码 const jonas {year: 1995,calcAge: function () {console.log(this);console.log(2038 - this.year);},greet: () > console.log(Hey ${this.firstName}), };jonas.greet();这个会输出什么&#xff1f; 这个我们上篇文章中讲过&#xff0c;箭头函数…

(五)、基于 LangChain 实现大模型应用程序开发 | 基于知识库的个性化问答 (文档加载 Document Loading)

&#x1f604; 大语言模型(Large Language Model, LLM), 可以回答许多不同的问题。但是大语言模型的知识来源于其训练数据集&#xff0c;并没有用户的信息&#xff08;比如用户的个人数据&#xff0c;公司的自有数据&#xff09;&#xff0c;也没有最新发生时事的信息&#xff…

算法-二叉树-简单-二叉树的最大和最小深度

记录一下算法题的学习7 二叉树的最大深度 题目&#xff1a;给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例分析&#xff…

概念解析 | 光电神经网络:optoelectronic neural network

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:光电神经网络。 概念解析 | 光电神经网络的原理、挑战与未来 1. 背景介绍 在过去的十年中,深度学习和神经网络在许多领域取得了显著的成就,如图像识别、自然语言处理、医疗…

【大数据开发】FineReport报表基础入门

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录 一 登录账号二 创建一个新的表格三 单元格扩展3.1 无扩展3.2 纵向扩展3.3 横向扩展 四 父子格…

代码随想录算法训练营第四十一天【动态规划part03】 | 343. 整数拆分、96.不同的二叉搜索树

343. 整数拆分 题目链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 求解思路&#xff1a; 动规五部曲 确定dp数组及其下标含义&#xff1a;dp[i] 拆分i&#xff0c;可以得到的最大乘积为dp[i]确定递推公式&#xff1a;从1开始遍…

一周互联网简讯 | 本周互联网发生了啥?(第3期)

1.百度T7跳槽字节3-1&#xff0c;总包145万&#xff0c;压力太大想降级 硕士毕业工作10年&#xff0c;一百度T7大头兵发文称&#xff0c;自己最近拿到字节3-1的offer&#xff0c;年包从现有的110万涨30%到145万。但是担心去字节后因为定的职级高需要带人&#xff0c;压力会很大…

nginx代理本地服务请求,避免跨域;前端图片压缩并上传

痛点 有时用vscode进行一些测试 请求不同端口服务、或者其他服务接口时时&#xff0c;老是会报跨域&#xff0c;非常的烦 所有就想用 nginx 进行请求代理&#xff0c;来解决这个痛点 nginx 下载地址&#xff1a;nginx: download 下载到某一目录&#xff1a; window下nginx相关…

10个值得关注的即时通讯软件开发趋势

作为即时通讯软件开发领域的专家&#xff0c;以下是我对即时通讯软件开发的十个值得关注的趋势的分享。 1. 云通信技术的进步 随着云计算和网络技术的不断发展&#xff0c;云通信技术在即时通讯软件开发中扮演着越来越重要的角色。通过使用云通信技术&#xff0c;开发者可以实…

文具办公产品展示预约小程序的作用如何

从整体来看&#xff0c;文具办公品牌/门店的生意来源于线下自然流量或线上自营商城/入驻第三方商城的的流量&#xff0c;线上多数情况都是以直接销售配送为主&#xff0c;但其实对文具品牌/门店而言还有信息展示、服务预约、在线咨询、产品介绍等需求。 虽然小区周边的消费者需…

vue安装three.js并创建第一个入门场景

vue安装three.js&#xff0c;并创建第一个入门场景 安装three.js npm install --save three引入three.js import * as THREE from threethree.js结构 three.js坐标 创建一个场景 scene场景&#xff0c;camera相机&#xff0c;renderer渲染器 创建一个场景 this.scene new T…

从矿源到指尖——周大福天然钻石的非凡实力

&#xff08;2023年11月20日&#xff0c;北京&#xff09;在近百年历程中&#xff0c;周大福珠宝集团一直致力珠宝工艺传承与创新设计的孕育&#xff0c;于1929年创立周大福品牌&#xff0c;凭借对中国传统黄金工艺的传承与创新、对中国传统文化的融合与发扬&#xff0c;将黄金…