| 命令名 | 快捷键 | 说明 |
|---|---|---|
| 编辑.复制 | CTRL + C CTRL + INSERT |
将当前选定的项复制到系统剪贴板。 |
| 编辑.剪切 | CTRL + X SHIFT + DELETE |
将当前选定的项移除到系统剪贴板。 |
| 编辑.循环应用剪贴板中的复制项 | CTRL + SHIFT + INS CTRL + SHIFT + V |
将项从“工具箱”的“剪贴板循环”选项卡粘贴在文件中的插入点,并自动选择粘贴的项。可通过重复按这些快捷键来查看剪贴板上的每个项。 |
| 编辑.转到下一个位置 | F8 | 将光标移动到下一项,如“任务列表”窗口中的任务或“查找结果”窗口中的搜索匹配项。每按一次 F8 键,就移动到列表中的下一个项。 |
| 编辑.转到上一个位置 | SHIFT + F8 | 在“任务列表”窗口或“查找结果”窗口中,将光标移动到上一项。 |
| 编辑.转到引用 | SHIFT + F12 | 显示代码中所选内容的引用。 |
| 编辑.打开文件 | CTRL + SHIFT + G | 显示“打开文件”对话框,在此可选择要打开的现有文件。 |
| 编辑.粘贴 | CTRL + V SHIFT + INSERT |
在插入点插入剪贴板的内容。 |
| 编辑.重复 | CTRL + SHIFT + Z CTRL + Y SHIFT + ALT + BACKSPACE |
还原上次撤消的操作。 |
| 编辑.取消选定 | ESC | 关闭菜单或对话框,取消正在进行的操作,或将焦点放在当前文档窗口中。仅在 .NET Framework 设计器中可用。 |
| 编辑.撤消 | ALT + BACKSPACE CTRL + Z |
撤消上一编辑操作。 |
| 文件.打印 | CTRL + P | 显示“打印”对话框,可在其中选择打印机设置。 |
| 文件.全部保存 | CTRL + SHIFT + S | 保存当前解决方案中的所有文档和外部文件项目中的任何文件。 |
| 文件.保存选定项 | CTRL + S | 保存当前项目中的选定项。 |
| 工具.转到命令行 | CTRL + / | 将插入符号放置在“标准”工具栏上的“查找/命令”框中。 |
| 视图.下一任务 | CTRL + SHIFT + F12 | 移到“任务列表”窗口中的下一个任务。 |
| 视图.弹出浏览上下文 | CTRL + SHIFT + 8 | 返回到上次执行浏览操作的位置。在“对象浏览器”或“类视图”窗口中可用。 |
| 视图.查看代码 | F7 | 在编辑器的“代码”视图中显示选定项。 |
| 视图.视图设计器 | SHIFT + F7 | 在编辑器的“设计”视图中显示选定项。 |
| 视图.Web向后定位 | ALT + 左箭头键 | 显示查看历史记录中的前一页。仅在“Web 浏览器”窗口中可用。 |
| 视图.Web向前定位 | ALT + 右箭头键 | 显示查看历史记录中的下一页。仅在“Web 浏览器”窗口中可用。 |
只有在 HTML 设计器中进行编辑时才能使用下列快捷组合键。某些组合键仅在该设计器的特定视图中可用。
| 命令名 | 快捷键 | 说明 |
|---|---|---|
| 编辑.列出成员 | CTRL + J | 编辑代码时,列出当前类的成员以完成语句。仅可用于 HTML 设计器的“HTML”视图。 |
| 编辑.参数信息 | CTRL + SHIFT + 空格键 | 基于当前语言显示包含当前参数信息的工具提示。仅可用于 HTML 编辑器的“HTML”视图。 |
| 编辑.视图底部 | CTRL + PAGE DOWN | 移动到当前文档末尾。仅可用于 HTML 设计器的“HTML”视图中可用。 |
| 编辑.视图顶部 | CTRL + PAGE UP(将文件另存为) | 移动到当前窗口的顶部。仅可用于 HTML 设计器的“HTML”视图中可用。 |
| 格式.粗体 | CTRL + B | 在粗体和正常之间切换选定文本。仅可用于 HTML 设计器的“设计”视图。 |
| 格式.书签 | CTRL + SHIFT + L | 显示“书签”对话框。仅可用于 HTML 设计器的“设计”视图。 |
| 格式.转换为超级链接 | CTRL + L | 选定文本后,显示“超级链接”对话框。仅可用于 HTML 设计器的“设计”视图。 |
| 格式.减少缩进 | CTRL + SHIFT + T | 将选定段落减少一个缩进单元。仅可用于 HTML 设计器的“设计”视图。 |
| 格式.增加缩进 | CTRL + T | 将选定段落缩进一个缩进单元。仅可用于 HTML 设计器的“设计”视图。 |
| 格式.斜体 | CTRL + I | 在斜体和正常之间切换选定文本。仅可用于 HTML 设计器的“设计”视图。 |
| 格式.锁定元素 | CTRL + SHIFT + K | 防止绝对定位的元素被意外移动。仅可用于 HTML 设计器的“设计”视图。 |
| 格式.显示网格 | CTRL + G | 切换显示网格。仅可用于 HTML 设计器的“设计”视图。 |
| 格式.网格线对齐 | CTRL + SHIFT + G | 指定使用不可见网格对齐元素。可以在“选项”对话框中“HTML 设计器”选项的“设计”窗格上设置网格间距,网格将在您下次打开文档时更改。仅可用于 HTML 设计器的“设计”视图。 |
| 格式.下划线 | CTRL + U | 在下划线和正常之间切换选定文本。仅可用于 HTML 设计器的“设计”视图。 |
| 表.在其左侧插入列 | CTRL + ALT + 左箭头键 | 将一列添加到表中当前列的左边。仅可用于 HTML 设计器的“设计”视图。 |
| 表.在其右侧插入列 | CTRL + ALT + 右箭头键 | 将一列添加到表中当前列的右边。仅可用于 HTML 设计器的“设计”视图。 |
| 表.在其上方插入行 | CTRL + ALT + 上箭头键 | 在表中的当前行之上添加一行。仅可用于 HTML 设计器的“设计”视图。 |
| 表.在其下方插入行 | CTRL + ALT + 下箭头键 | 在表中的当前行之下添加一行。仅可用于 HTML 设计器的“设计”视图。 |
| 视图.详细信息 | CTRL + SHIFT + Q | 显示不具有可视化表示形式的 HTML 元素的信号图标,如绝对定位元素的注释、脚本和定位点。仅可用于 HTML 设计器的“设计”视图。 |
| 视图.下一个视图 | CTRL + PAGE DOWN | 从“设计”视图切换到“HTML”视图,反之亦然。仅可用于 HTML 设计器的“设计”视图。 |
| 视图.可视边框 | CTRL + Q | 在支持 BORDER 属性的 HTML 元素(如表、表单元格和间隔)周围显示 1 像素的边框并将该属性设置为零。仅可用于 HTML 设计器的“设计”视图。 |
| 命令名 | 快捷键 | 说明 |
|---|---|---|
| 架构.折叠 | CTRL + (-) | 折叠嵌套元素。仅用于 XML 设计器的“架构”视图。 |
| 架构.展开 | CTRL + (=) | 展开嵌套元素。仅用于 XML 设计器的“架构”视图。 |
下列快捷组合键可用于在设计图面上移动和选择控件以及更改控件的大小。
| 命令名 | 快捷键 | 说明 |
|---|---|---|
| 编辑.下移控件 | CTRL + 下箭头键 | 在设计图面上,将选定的控件以 1 为增量向下移动。 |
| 编辑.将控件移动到下侧网格 | 下箭头键 | 在设计图面上,将选定的控件以 8 为增量向下移动。 |
| 编辑.左移控件 | CTRL + 左箭头键 | 在设计图面上,将控件以 1 为增量向左移动。 |
| 编辑.将控件移动到左侧网格 | 左箭头键 | 在设计图面上,将控件以 8 为增量向左移动。 |
| 编辑.右移控件 | CTRL + 右箭头键 | 在设计图面上,将控件以 1 为增量向右移动。 |
| 编辑.将控件移动到右侧网格 | 右箭头键 | 在设计图面上,将控件以 8 为增量向右移动。 |
| 编辑.上移控件 | CTRL + 上箭头键 | 在设计图面上,将控件以 1 为增量向上移动。 |
| 编辑.将控件移动到上侧网格 | 上箭头键 | 在设计图面上,将控件以 8 为增量向上移动。 |
| 编辑.选择下一个控件 | TAB 键 | 移动到页上的下一控件处。 |
| 编辑.选择上一个控件 | SHIFT + TAB 键 | 移回到页上上次选定的控件处。 |
| 编辑.向下调整控件大小 | CTRL + SHIFT + 下箭头键 | 在设计图面上,以 1 为增量,增加控件的高度。 |
| 编辑.将控件调大到下侧网格 | SHIFT + 下箭头键 | 在设计图面上,以 8 为增量,增加控件的高度。 |
| 编辑.向左调整控件大小 | CTRL + SHIFT + 左箭头键 | 在设计图面上,以 1 为增量,减少控件的宽度。 |
| 编辑.将控件调大到左侧网格 | SHIFT + 左箭头键 | 在设计图面上,以 8 为增量,减少控件的宽度。 |
| 编辑.向右调整控件大小 | CTRL + SHIFT + 右箭头键 | 在设计图面上,以 1 为增量,增加控件的宽度。 |
| 编辑.将控件调大到右侧网格 | SHIFT + 左箭头键 | 在设计图面上,以 8 为增量,增加控件的宽度。 |
| 编辑.向上调整控件大小 | CTRL + SHIFT + 上箭头键 | 在设计图面上,以 1 为增量,减少控件的高度。 |
| 编辑.将控件调大到上侧网格 | SHIFT + 上箭头键 | 在设计图面上,以 8 为增量,减少控件的高度。 |
下列快捷组合键可在调试代码时使用。
| 命令名 | 快捷键 | 说明 |
|---|---|---|
| 调试.应用代码更改 | ALT + F10 | 开始一个“编辑”或“继续”生成,以应用对正在调试的代码所作的更改。 |
| 调试.自动窗口 | CTRL + ALT + V,A | 显示“自动”窗口,以查看当前过程内当前执行行范围中的当前变量的值。 |
| 调试.全部中断 | CTRL + ALT+ Break | 临时停止执行调试会话中的所有进程。仅适用于“运行”模式。 |
| 调试.断点 | CTRL + ALT + B | 显示“断点”对话框,在此可添加和修改断点。 |
| 调试.调用堆栈 | CTRL + ALT + C | 显示“调用堆栈”窗口,以显示当前执行线程的所有活动过程或堆栈帧列表。仅适用于“运行”模式。 |
| 调试.清除所有断点 | CTRL + SHIFT + F9 | 清除项目中的所有断点。 |
| 调试.反汇编 | CTRL + ALT + D | 显示“反汇编”窗口。 |
| 调试.启用断点 | CTRL + F9 | 在当前代码行设置断点。 |
| 调试.异常 | CTRL + ALT + E | 显示“异常”对话框。 |
| 调试.即时 | CTRL + ALT + I | 显示“即时”窗口,在此可计算表达式和执行个别命令。 |
| 调试.局部变量 | CTRL + ALT + V,L | 显示“局部变量”窗口,以查看当前堆栈帧中每个过程的变量及其值。 |
| 调试.内存1 | CTRL + ALT + M,1 键 | 显示“内存 1”窗口,以查看在“监视”或“变量”窗口中不能清楚显示的大缓存区、字符串和其他数据。 |
| 调试.内存2 | CTRL + ALT + M,2 键 | 显示“内存 2”窗口,查看在“监视”或“变量”窗口中不能清楚地显示的大缓冲区、字符串和其他数据。 |
| 调试.内存3 | CTRL + ALT + M,3 键 | 显示“内存 3”窗口,查看在“监视”或“变量”窗口中不能清楚地显示的大缓冲区、字符串和其他数据。 |
| 调试.内存4 | CTRL + ALT + M,4 键 | 显示“内存 4”窗口,查看在“监视”或“变量”窗口中不能清楚地显示的大缓冲区、字符串和其他数据。 |
| 调试.模块 | CTRL + ALT + U | 显示“模块”窗口,该窗口允许查看由程序使用的 .dll 或 .exe 文件。在多处理调试中,可以右击并选择“显示所有程序的模块”。 |
| 调试.新断点 | CTRL + B | 在当前代码行中插入或清除断点。 |
| 调试.快速监视 | CTRL + ALT + Q | 显示带有选定表达式的当前值的“快速监视”对话框。仅适用于“中断”模式。使用该命令可检查尚未为其定义监视表达式的变量、属性或其他表达式的当前值。 |
| 调试.寄存器 | CTRL + ALT + G | 显示“寄存器”窗口,该窗口显示用于调试本机代码应用程序的寄存器内容。 |
| 调试.重新启动 | CTRL + SHIFT + F5 | 终止调试会话,重新生成,然后从开始处开始运行应用程序。可用于“中断”模式和“运行”模式。 |
| 调试.运行文档 | CTRL + ALT + N | 显示“运行文档”窗口,该窗口显示正处于调试过程中的文档集。适用于“运行”模式。 |
| 调试.运行到光标处 | CTRL + F10 | 在“中断”模式下,从当前语句继续执行代码,直到选定语句。“当前执行行”边距指示器出现在“页边距指示符”栏中。 在“设计”模式下,启动调试器并执行代码,直到光标位置。 |
| 调试.设置下一语句 | CTRL + SHIFT + F10 | 在选择的代码行上设置执行点。 |
| 调试.显示下一语句 | ALT + 数字键区中的 * | 突出显示要执行的下一条语句。 |
| 调试.启动 | F5 | 自动附加调式器,并从“<Project> 属性”对话框中指定的启动项目中运行应用程序。如果为“中断”模式,则更改为“继续”。 |
| 调试.开始执行不调试 | CTRL + F5 | 在不调用调试器的情况下运行代码。 |
| 调试.逐语句 | F11 | 在执行进入函数调用后,逐条语句执行代码。 |
| 调试.跳出 | SHIFT + F11 | 执行当前执行点所处函数的剩余行。 |
| 调试.逐过程 | F10 | 执行下一行代码,但不执行任何函数调用。 |
| 调试.停止调试 | SHIFT + F5 | 停止运行程序中的当前应用程序。可用于“中断”模式和“运行”模式。 |
| 调试.This | CTRL + ALT + V,T | 显示“This”窗口,该窗口允许查看与当前方法关联的对象的数据成员。 |
| 调试.线程 | CTRL + ALT + H | 显示“线程”窗口,查看用于当前进程的所有线程及其信息。 |
| 调试.切换断点 | F9 | 在当前行设置或移除断点。 |
| 调试.切换反汇编 | CTRL + F11 | 显示当前源文件的反汇编信息。仅适用于“中断”模式。 |
| 调试.监视1 | CTRL + ALT + W,1 键 | 显示“Watch1”窗口,以查看所选变量或监视表达式的值。 |
| 调试.监视2 | CTRL + ALT + W,2 键 | 显示“Watch2”窗口,以查看所选变量或监视表达式的值。 |
| 调试.监视3 | CTRL + ALT + W,3 键 | 显示“Watch3”窗口,以查看所选变量或监视表达式的值。 |
| 调试.监视4 | CTRL + ALT + W,4 键 | 显示“Watch4”窗口,以查看所选变量或监视表达式的值。 |
| 工具.调试进程 | CTRL + ALT + P | 显示“进程”对话框,该对话框允许在单个解决方案中同时调试多个程序。 |
下列快捷组合键可用于“查找”、“替换”、“在文件中查找”和“在文件中替换”对话框。
| 命令名 | 快捷键 | 说明 |
|---|---|---|
| 编辑.查找 | CTRL + F | 显示“查找”对话框。 |
| 编辑.在文件中查找 | CTRL + SHIFT + F | 显示“在文件中查找”对话框。 |
| 编辑.查找下一个 | F3 | 查找上次搜索文本的下一个匹配项。 |
| 编辑.查找下一个选定项 | CTRL + F3 | 在文档中查找当前选定文本的下一个匹配项。 |
| 编辑.查找上一个 | SHIFT + F3 | 查找搜索文本的上一个匹配项。 |
| 编辑.查找上一个选定项 | CTRL + SHIFT + F3 | 查找当前选定文本的上一匹配项或者插入符号处的单词。 |
| 编辑.转到查找组合框 | CTRL + D | 将插入符号放置在“标准”工具栏上的“查找/命令”行中。 |
| 编辑.隐藏文本 | ALT + F3,H | 选择或清除“查找”对话框的“搜索隐藏文本”选项。 |
| 编辑.渐进式搜索 | CTRL + I | 启动渐进式搜索。如果启动了渐进式搜索,但尚未键入任何字符,请恢复上一模式。如果已找到文本,则搜索下一匹配项。 |
| 编辑.大小写匹配 | ALT + F3,C。 | 选择或清除“查找”和“替换”操作的“大小写匹配”选项。 |
| 编辑.正则表达式 | ALT + F3,R | 选择或清除“正则表达式”选项,以便特殊字符可用于“查找”和“替换”操作。 |
| 编辑.替换 | CTRL + H | 显示“替换”对话框。 |
| 编辑.在文件中替换 | CTRL + SHIFT + H | 显示“在文件中替换”对话框。 |
| 编辑.反向渐进式搜索 | CTRL + SHIFT + I | 更改渐进式搜索的方向,从文件尾开始向文件头搜索。 |
| 编辑.停止搜索 | ALT + F3,S | 暂停当前的“在文件中查找”操作。 |
| 编辑.向上 | ALT + F3,B | 选择或清除“查找”和“替换”操作的“向上搜索”选项。 |
| 编辑.全字匹配 | ALT + F3,W | 选择或清除“查找”和“替换”操作的“全字匹配”选项。 |
| 编辑.通配符 | ALT + F3,P | 选择或清除“查找”和“替换”操作的“通配符”选项。 |
下列快捷组合键可用于数据库设计器或查询设计器。
| 命令名 | 快捷键 | 说明 |
|---|---|---|
| 数据库.运行 | CTRL + E | 运行当前活动的数据库对象。 |
| 数据库.运行选定内容 | CTRL + Q | 运行 SQL 编辑器中的当前选择。 |
| 数据库.逐语句 | ALT + F5 | 使当前的活动数据库对象按步骤进入调试模式。 |
| 查询.运行 | CTRL + R | 执行查询。仅在“查询设计器”中可用。 |
| 视图.关系图 | CTRL +1 键 | 显示“查询”设计器的“关系图”窗格。仅在“查询”设计器中可用。 |
| 视图.网格 | CTRL + 2 键 | 显示“查询”设计器的“网格”窗格。仅在“查询”设计器中可用。 |
| 视图.结果 | CTRL +4 键 | 显示“查询”设计器的“结果”窗格。仅在“查询”设计器中可用。 |
| 视图.SQL | CTRL +3 键 | 显示“查询”设计器的“SQL”窗格。仅在“查询”设计器中可用。 |
下列快捷组合键可在文本编辑器中用于在打开的文档内进行移动。
| 命令名 | 快捷键 | 说明 |
|---|---|---|
| 编辑.左移字符 | 左箭头键 | 将光标向左移动一个字符。仅在 .NET Framework 设计器中可用。 |
| 编辑.右移字符 | 右箭头键 | 将光标向右移动一个字符。仅在 .NET Framework 设计器中可用 |
| 编辑.文档结尾 | CTRL + END | 将插入点移动到文档的最后一行。 |
| 编辑.文档开始 | CTRL + HOME | 将插入点移动到文档首行。 |
| 编辑.转到 | CTRL + G | 显示“转到行”对话框。 |
| 编辑.转到大括号 | CTRL + ] | 将插入点移动到文档中的下一个大括号处。 |
| 编辑.向下移动一行 | 下箭头键 | 将光标下移一行。 |
| 编辑.行尾 | END | 将光标移至当前行的结尾。 |
| 编辑.行首 | HOME | 将光标移至当前行的开头。 |
| 编辑.向上移动一行 | 上箭头键 | 将光标上移一行。 |
| 编辑.下一书签 | CTRL + K,CTRL + N | 移动到文档中下一个书签处。 |
| 编辑.向下翻页 | PAGE DOWN | 在编辑器窗口中向下滚动一屏。 |
| 编辑.向上翻页 | PAGE UP | 在编辑器窗口中向上滚动一屏。 |
| 编辑.上一书签 | CTRL + K,CTRL + P | 移动到上一书签。 |
| 编辑.快速信息 | CTRL + K,CTRL + I | 基于当前语言显示“快速信息”。 |
| 编辑.向下滚动一行 | CTRL + 下箭头键 | 将文本向下滚动一行。仅在文本编辑器中可用。 |
| 编辑.向上滚动一行 | CTRL + 上箭头键 | 将文本向上滚动一行。仅在文本编辑器中可用。 |
| 编辑.下一字 | CTRL + 右箭头键 | 将插入点向右移动一个单词。 |
| 编辑.上一字 | CTRL + 左箭头键 | 将插入点向左移动一个单词。 |
| 视图.浏览下一个 | CTRL + SHIFT + 1 | 定位到项的下一个定义、声明或引用。在“对象浏览器”和“类视图”窗口中可用。 |
| 视图.浏览上一个 | CTRL + SHIFT + 2 | 定位到项的上一个定义、声明或引用。在“对象浏览器”和“类视图”窗口中可用。 |
下列快捷组合键可在文本编辑器中用于在打开的文档中选择文本。
| 命令名 | 快捷键 | 说明 |
|---|---|---|
| 编辑.向左扩展一个字符 | SHIFT + 左箭头键 | 将光标左移一个字符以扩展所选内容。仅在 .NET Framework 设计器中可用。 |
| 编辑.向左扩展一个字符列 | SHIFT + ALT + 左箭头键 | 将光标左移一个字符以扩展列选择。 |
| 编辑.向右扩展一个字符 | SHIFT + 右箭头键 | 将光标右移一个字符以扩展所选内容。仅在 .NET Framework 设计器中可用。 |
| 编辑.向右扩展一个字符列 | SHIFT + ALT + 右箭头键 | 将光标右移一个字符以扩展列选择。 |
| 编辑.文档结尾扩展 | CTRL + SHIFT + END | 选择从插入点到文档最后一行的文本。 |
| 编辑.文档开始扩展 | CTRL + SHIFT + HOME | 选择从插入点到文档首行的文本。 |
| 编辑.扩展转到大括号 | CTRL + SHIFT + ] | 将插入点移动到下一个大括号处以扩展选定内容。 |
| 编辑.向下扩展一行 | SHIFT + 下箭头键 | 从插入点位置开始,将选定文本向下扩展一行。 |
| 编辑.向下扩展列 | SHIFT + ALT + 下箭头键 | 将光标下移一行以扩展列的选定内容。 |
| 编辑.扩展到行尾 | SHIFT + END | 选择从插入点到当前行行尾的文本。 |
| 编辑.行尾扩展列 | SHIFT + ALT + END | 将插入点移动到行尾以扩展列的选定内容。 |
| 编辑.扩展到行首 | SHIFT + HOME | 选择从插入点到行首的文本。 |
| 编辑.行首扩展列 | SHIFT + ALT + HOME | 将插入点移到行首以扩展列选择。 |
| 编辑.向上扩展一行 | SHIFT + 上箭头键 | 从插入点位置开始向上逐行选择文本。 |
| 编辑.向上扩展列 | SHIFT + ALT + 上箭头键 | 将光标上移一行以扩展列的选定内容。 |
| 编辑.向下扩展一页 | SHIFT + PAGE DOWN | 将选定内容向下扩展一页。 |
| 编辑.向上扩展一页 | SHIFT + PAGE UP | 将选定内容向上扩展一页。 |
| 编辑.全选 | CTRL + A | 选择当前文档中的所有内容。 |
| 编辑.选择当前字 | CTRL + W | 选择包含插入点的单词,或插入点右侧的单词。 |
| 编辑.选择到最后一个返回 | CTRL + = | 选择编辑器中当前位置到编辑器中前一位置之间的内容。 |
| 编辑.扩展到视图底部 | CTRL + SHIFT + PAGE DOWN | 将光标移动到视图中的最后一行以扩展选定内容。 |
| 编辑.扩展到视图顶部 | CTRL + SHIFT + PAGE UP | 将选定内容扩展到当前窗口的顶部。 |
| 编辑.扩展到下一字 | CTRL + SHIFT + 右箭头键 | 将选定内容向右扩展一个单词的位置。 |
| 编辑.向后扩展一个字列 | CTRL + SHIFT + ALT + 右箭头键 | 将光标右移一个单词以扩展列选择。 |
| 编辑.扩展到上一字 | CTRL + SHIFT + 左箭头键 | 将选定内容向左扩展一个单词的位置。 |
| 编辑.向前扩展一个字列 | CTRL + SHIFT + ALT + 左箭头键 | 将光标左移一个单词以扩展列选择。 |
下列快捷组合键可在文本编辑器中用于在打开的文档中删除、移动或者格式化文本。
| 命令名 | 快捷键 | 说明 |
|---|---|---|
| 编辑.分行 | ENTER SHIFT + ENTER |
插入新行。 |
| 编辑.字符转置 | CTRL + T | 交换插入点两边的字符。例如,AC| BD 变成 AB| CD。仅在文本编辑器中可用。 |
| 编辑.清除书签 | CTRL + K,CTRL + L | 移除当前文档中所有未命名的书签。 |
| 编辑.折叠到定义 | CTRL + M,CTRL + O | 自动确定在代码中创建区域的逻辑边界(如过程),然后隐藏它们。 |
| 编辑.注释选定内容 | CTRL + K,CTRL + C | 使用编程语言的正确注释语法将代码的当前行标记为注释。 |
| 编辑.完成单词 | ALT + 右箭头键 CTRL + 空格键 |
显示基于当前语言的“完整单词”。 |
| 编辑.删除 | DELETE | 删除光标右侧的一个字符。 |
| 编辑.向后删除 | BACKSPACE SHIFT + BACKSPACE |
删除光标左侧的一个字符。 |
| 编辑.删除水平空白 | CTRL + K,CTRL + \ | 折叠选定内容中的空白,如果没有选定内容,则删除与光标相邻的空白。 |
| 编辑.编排文档格式 | CTRL + K,CTRL + D | 按照“选项”对话框“文本编辑器”部分中语言的“格式设置”窗格上指定的设置,对语言应用缩进和空格格式设置。 |
| 编辑.格式化选定内容 | CTRL + K,CTRL + F | 根据周围的代码行,正确缩进选定的代码行。 |
| 编辑.隐藏选定内容 | CTRL + M,CTRL + H | 隐藏选定文本。信号图标标记隐藏文本在文件中的位置。 |
| 编辑.插入制表符 | TAB | 将文本行缩进指定数量的空格,如 5 个。 |
| 编辑.剪切行 | CTRL + L | 将所有选定的行剪切到“剪贴板”,若尚未选定任何内容,则将当前行剪切到剪贴板。 |
| 编辑.删除行 | CTRL + SHIFT + L | 删除所有选定行;如果没有选定行,则删除当前行。 |
| 编辑.上开新行 | CTRL + ENTER | 在插入点之上插入一个空行。 |
| 编辑.下开新行 | CTRL + SHIFT + ENTER | 在插入点之下插入一个空行。 |
| 编辑.行转置 | SHIFT + ALT + T | 将包含插入点的行移动到下一行之下。 |
| 编辑.转换为小写 | CTRL + U | 将选定文本更改为小写字符。 |
| 编辑.转换为大写 | CTRL + SHIFT + U | 将选定文本更改为大写字符。 |
ADO.NET作为微软最新的数据访问技术,已经在企业开发中得到了广泛的应用。对于一线的开发人员来说,掌握基本的概念和技术之后,提高应用水平和解决实际问题的最有效手段,莫过于相互交流彼此的最佳时间经验经验。在这篇文章中,两位ADO.NET专家向读者毫无保留地、详尽地介绍了很多实用经验。
简介
本文为您提供了在Microsoft ADO.NET应用程序中实现和获得最佳性能、可伸缩性以及功能的最佳解决方案;同时也讲述了使用ADO.NET中可用对象的最佳实践;并提出一些有助于优化ADO.NET应用程序设计的建议。
.NET框架数据提供程序
.NET框架中的数据提供程序(Data Provider)在应用程序和数据源之间起到桥梁作用。.NET框架数据提供程序能够从数据源中返回查询结果、对数据源执行命令、将DataSet中的更改传播给数据源。本文包括有关哪个.NET框架数据提供程序是最适合您需要的一些技巧。
使用哪个.NET框架数据提供程序?
为了使您的应用程序获得最佳性能,请使用最适合您的数据源的.NET框架数据提供程序。有许多数据提供程序可供您的应用程序选用。
连接到SQL Server 7.0或更高版本
为了在连接到Microsoft SQL Server 7.0或更高版本时获得最佳性能,请使用SQL Server .NET数据提供程序。SQL Server .NET数据提供程序的设计目的就在于不通过任何附加技术层就可以直接访问SQL Server。
连接到ODBC数据源
ODBC .NET数据提供程序可在Microsoft.Data.ODBC命名空间中找到,它的体系结构与用于SQL Server和OLE DB的.NET数据提供程序相同。ODBC .NET数据提供程序遵循命名约定-以“ODBC”为前缀(例如,OdbcConnection),并使用标准ODBC连接字符串。
使用DataReader、DataSet、DataAdapter和DataView
ADO.NET提供以下两个对象,用于检索关系数据并将其存储在内存中:DataSet和DataReader。DataSet提供一个内存中数据的关系表示形式,一整套包括一些表在内的数据(这些表包含数据、对数据进行排序并约束数据),以及表之间的关系。DataReader提供一个来自数据库的快速、仅向前、只读数据流。
当使用DataSet时,经常会利用DataAdapter(也可能是CommandBuilder)与数据源进行交互。当使用DataSet时,也可以利用DataView对DataSet中的数据应用排序和筛选。也可以从DataSet继承,创建强类型DataSet,用于将表、行和列作为强类型对象属性公开。
下列主题包括的信息涉及:使用DataSet或DataReader的最佳时机、如何优化访问它们所包含数据、以及如何优化使用DataAdapter(包括CommandBuilder)和DataView的技巧。
DataSet与DataReader
当设计应用程序时,要考虑应用程序所需功能的等级,以确定使用DataSet或者是DataReader。
要通过应用程序执行以下操作,就要使用DataSet:
1) 在结果的多个离散表之间进行导航。
2) 操作来自多个数据源(例如,来自多个数据库、一个XML文件和一个电子表格的混合数据)的数据。
3) 在各层之间交换数据或使用XML Web服务。与DataReader不同的是,DataSet能传递给远程客户端。
4) 重用同样的记录集合,以便通过缓存获得性能改善(例如排序、搜索或筛选数据)。
5) 每条记录都需要执行大量处理。对使用DataReader返回的每一行进行扩展处理会延长服务于DataReader的连接的必要时间,这影响了性能。
6) 使用XML操作对数据进行操作,例如可扩展样式表语言转换(XSLT转换)或XPath查询。
对于下列情况,要在应用程序中使用DataReader:
1) 不需要缓存数据。
2) 要处理的结果集太大,内存中放不下。
3) 一旦需要以仅向前、只读方式快速访问数据。
注填充DataSet时,DataAdapter使用DataReader。因此,使用DataAdapter取代DataSet提升的性能表现为节省了DataSet占用内存和填充DataSet需要的循环。一般来说,此性能提升只是象征性的,因此,设计决策应以所需功能为基础。
使用强类型DataSet的好处
DataSet的另一个好处是可被继承以创建一个强类型DataSet。强类型DataSet的好处包括设计时类型检查,以及Microsoft Visual Studio.NET用于强类型DataSet语句结束所带来的好处。修改了DataSet的架构或关系结构后,就可以创建一个强类型DataSet,将行和列作为对象的属性公开,而不是作为集合中的项公开。例如,不公开客户表中行的姓名列,而公开Customer对象的Name属性。类型化DataSet从DataSet类派生,因此不会牺牲DataSet的任何功能。也就是说,类型化DataSet仍能远程访问,并作为数据绑定控件(例如DataGrid)的数据源提供。如果架构事先不可知,仍能受益于通用DataSet的功能,但却不能受益于强类型DataSet的附加功能。
处理强类型DataSet中的空引用
使用强类型DataSet时,可以使用DataSet的XML架构定义语言(XSD)架构来确保强类型DataSet可以正确处理空引用。nullValue标识符使您可用一个指定的值String.Empty代替DBNull、保留空引用或引发异常。选择哪个选项取决于应用程序的上下文。默认情况下,如果遇到空引用,就会引发异常。
刷新DataSet中的数据
如果想用服务器上的更新值刷新DataSet中的值,就使用DataAdapter.Fill。如果有在DataTable上定义的主键,DataAdapter.Fill会根据主键进行新行匹配,并且当更改到现有行时应用服务器上的值。即使刷新之前修改了这些数据,刷新行的RowState仍被设置为Unchanged。注意,如果没有为DataTable定义主键,DataAdapter.Fill就用可能重复的主键值添加新行。
如果想用来自服务器的当前值刷新表,并同时保留对表中的行所做的任何更改,必须首先用DataAdapter.Fill填充表,并填充一个新的DataTable,然后用preserveChanges值true将DataTable合并到DataSet之中。
在DataSet中搜索数据
在DataSet中查询与特定条件相匹配的行时,可以利用基于索引的查找提高搜索性能。当将PrimaryKey值赋给DataTable时,会创建一个索引。当给DataTable创建DataView时,也会创建一个索引。下面是一些利用基于索引进行查找的技巧。
1) 如果对组成DataTable的PrimaryKey的列进行查询,要使用DataTable.Rows.Find而不是DataTable.Select。
2) 对于涉及到非主键列的查询,可以使用DataView为数据的多个查询提高性能。当将排序顺序应用到DataView时,就会建立一个搜索时使用的索引。DataView公开Find和FindRows方法,以便查询基础DataTable中的数据。
3) 如果不需要表的排序视图,仍可以通过为DataTable创建DataView来利用基于索引的查找。注意,只有对数据执行多个查询操作时,这样才会带来好处。如果只执行单一查询,创建索引所需要的处理就会降低使用索引所带来的性能提升。
DataView构造
如果创建了DataView,并且修改了Sort、RowFilter或RowStateFilter属性,DataView就会为基础DataTable中的数据建立索引。创建DataView对象时,要使用DataView构造函数,它用Sort、RowFilter和RowStateFilter值作为构造函数参数(与基础DataTable一起)。结果是创建了一次索引。创建一个“空”DataView并随后设置Sort、RowFilter或RowStateFilter属性,会导致索引至少创建两次。
分页
ADO.NET可以显式控制从数据源中返回什么样的数据,以及在DataSet中本地缓存多少数据。对查询结果的分页没有唯一的答案,但下面有一些设计应用程序时应该考虑的技巧。
1) 避免使用带有startRecord和maxRecords值的DataAdapter.Fill重载。当以这种方式填充DataSet时,只有maxRecords参数(从startRecord参数标识的记录开始)指定的记录数量用于填充DataSet,但无论如何总是返回完整的查询。这就会引起不必要的处理,用于读取“不需要的”记录;而且为了返回附加记录,会耗尽不必要的服务器资源。
2) 用于每次只返回一页记录的技术是创建SQL语句,将WHERE子句以及ORDER BY子句和TOP谓词组合起来。此技术取决于存在一种可唯一标识每一行的办法。当浏览下一页记录时,修改WHERE子句使之包含所有唯一标识符大于当前页最后一个唯一标识符的记录。当浏览上一页记录时,修改WHERE子句使之返回所有唯一标识符小于当前页第一个唯一标识符的记录。两种查询都只返回记录的TOP页。当浏览上一页时,需要以降序为结果排序。这将有效地返回查询的最后一页(如果需要,显示之前也许要重新排序结果)。
3) 另一项每次只返回一页记录的技术是创建SQL语句,将TOP谓词和嵌入式SELECT语句的使用结合在一起。此技术并不依赖于存在一种可唯一标识每一行的办法。使用这项技术的第一步是将所需页的数量与页大小相乘。然后将结果传递给SQL Query的TOP谓词,该查询以升序排列。再将此查询嵌入到另一个查询中,后者从降序排列的嵌入式查询结果中选择TOP页大小。实质上,返回的是嵌入式查询的最后一页。例如,要返回查询结果的第三页(页大小是10),应该书写如下所示的命令:
SELECT TOP 10 * FROM (SELECT TOP 30 * FROM Customers ORDER BY Id ASC) AS Table1 ORDER BY Id DESC
注意:从查询中返回的结果页以降序显示。如果需要,应该重新排序。
1) 如果数据不经常变动,可以在DataSet中本地维护一个记录缓存,以此提高性能。例如,可以在本地DataSet中存储10页有用的数据,并且只有当用户浏览超出缓存第一页和最后一页时,才从数据源中查询新数据。
用架构填充DataSet
当用数据填充DataSet时,DataAdapter.Fill方法使用DataSet的现有架构,并使用从SelectCommand返回的数据填充它。如果在DataSet中没有表名与要被填充的表名相匹配,Fill方法就会创建一个表。默认情况下,Fill仅定义列和列类型。
通过设置DataAdapter的MissingSchemaAction属性,可以重写Fill的默认行为。例如,要让Fill创建一个表架构,并且还包括主键信息、唯一约束、列属性、是否允许为空、最大列长度、只读列和自动增量的列,就要将DataAdapter.MissingSchemaAction指定为MissingSchemaAction.AddWithKey。或者,在调用DataAdapter.Fill前,可以调用DataAdapter.FillSchema来确保当填充DataSet时架构已到位。
对FillSchema的调用会产生一个到服务器的额外行程,用于检索附加架构信息。为了获得最佳性能,需要在调用Fill之前指定DataSet的架构,或者设置DataAdapter的MissingSchemaAction。
使用CommandBuilder的最佳实践
假设SelectCommand执行单一表SELECT,CommandBuilder就会以DataAdapter的SelectCommand属性为基础自动生成DataAdapter的InsertCommand、UpdateCommand、和DeleteCommand属性。下面是为获得最佳性能而使用CommandBuilder的一些技巧。
1) CommandBuilder的使用应该限制在设计时或即席方案中。生成DataAdapter命令属性所必需的处理会影响性能。如果预先知道INSERT/UPDATE/DELETE语句的内容,就显式设置它们。一个比较好的设计技巧是,为INSERT/UPDATE/DELETE命令创建存储过程并显式配置DataAdapter命令属性以使用它们。
2) CommandBuilder使用DataAdapter的SelectCommand属性确定其他命令属性的值。如果DataAdapter的SelectCommand本身曾经更改过,确保调用RefreshSchema以更新命令属性。
3) 如果DataAdapter命令属性为空(命令属性默认情况下为空),CommandBuilder仅仅为它生成一条命令。如果显式设置了命令属性,CommandBuilder不会重写它。如果希望CommandBuilder为以前已经设置过的命令属性生成命令,就将命令属性设置为空。
批处理SQL语句
很多数据库支持将多条命令合并或批处理成一条单一命令执行。例如,SQL Server使您可以用分号“;”分隔命令。将多条命令合并成单一命令,能减少到服务器的行程数,并提高应用程序的性能。例如,可以将所有预定的删除在应用程序中本地存储起来,然后再发出一条批处理命令调用,从数据源删除它们。
虽然这样做确实能提高性能,但是,当对DataSet中的数据更新进行管理时,可能会增加应用程序的复杂性。要保持简单,可能要在DataSet中为每个DataTable创建一个DataAdapter。
用多个表填充DataSet
如果使用批处理SQL语句检索多个表并填充DataSet,第一个表用指定给Fill方法的表名命名。后面的表用指定给Fill方法的表名加上一个从1开始并且增量为1的数字命名。例如,如果运行下面的代码:
'Visual Basic Dim da As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Customers; SELECT * FROM Orders;", myConnection) Dim ds As DataSet = New DataSet() da.Fill(ds, "Customers") //C# SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Customers; SELECT * FROM Orders;", myConnection); DataSet ds = new DataSet(); da.Fill(ds, "Customers");
来自Customers表的数据放在名为“Customers”的DataTable中。来自Orders表的数据放在名为“Customers1”的DataTable中。
填充完DataSet之后,可以很容易地将“Customers1”表的TableName属性改为“Orders”。但是,后面的填充会导致“Customers”表被重新填充,而“Orders”表会被忽略,并创建另外一个“Customers1”表。为了对这种情况作出补救,创建一个DataTableMapping,将“Customers1”映射到“Orders”,并为其他后面的表创建其他的表映射。例如:
'Visual Basic Dim da As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Customers; SELECT * FROM Orders;", myConnection) da.TableMappings.Add("Customers1", "Orders") Dim ds As DataSet = New DataSet() da.Fill(ds, "Customers") //C# SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Customers; SELECT * FROM Orders;", myConnection); da.TableMappings.Add("Customers1", "Orders"); DataSet ds = new DataSet(); da.Fill(ds, "Customers");
使用DataReader
下面是一些使用DataReader获得最佳性能的技巧,同时还回答了一些关于使用DataReader的常见问题。
1) 在访问相关Command的任何输出参数之前,必须关闭DataReader。
2) 完成读数据之后总是要关闭DataReader。如果使用Connection只是用于返回DataReader,那么关闭DataReader之后立刻关闭它。
另外一个显式关闭Connection的方法是将CommandBehavior.CloseConnection传递给ExecuteReader方法,以确保相关的连接在关闭DataReader时被关闭。如果从一个方法返回DataReader,而且不能控制DataReader或相关连接的关闭,则这样做特别有用。
1) 不能在层之间远程访问DataReader。DataReader是为已连接好的数据访问设计的。
2) 当访问列数据时,使用类型化访问器,例如,GetString、GetInt32等。这使您不用进行将GetValue返回的Object强制转换成特定类型所需的处理。
3) 一个单一连接每次只能打开一个DataReader。在ADO中,如果打开一个单一连接,并且请求两个使用只进、只读游标的记录集,那么ADO会在游标生存期内隐式打开第二个、未池化的到数据存储区的连接,然后再隐式关闭该连接。对于ADO.NET,“秘密”完成的动作很少。如果想在相同的数据存储区上同时打开两个DataReaders,就必须显式创建两个连接,每个DataReader一个。这是ADO.NET为池化连接的使用提供更多控制的一种方法。
4) 默认情况下,DataReader每次Read时都要将整行加载到内存。这允许在当前行内随机访问列。如果不需要这种随机访问,为了提高性能,就将CommandBehavior.SequentialAccess传递给ExecuteReader调用。这将DataReader的默认行为更改为仅在请求时将数据加载到内存。注意,CommandBehavior.SequentialAccess要求顺序访问返回的列。也就是说,一旦读过返回的列,就不能再读它的值了。
5) 如果已经完成读取来自DataReader的数据,但仍然有大量挂起的未读结果,就在调用DataReader的Close之前先调用Command的Cancel。调用DataReader的Close会导致在关闭游标之前检索挂起的结果并清空流。调用Command的Cancel会放弃服务器上的结果,这样,DataReader在关闭的时候就不必读这些结果。如果要从Command返回输出参数,还要调用Cancel放弃它们。如果需要读取任何输出参数,不要调用Command的Cancel,只要调用DataReader的Close即可。
二进制大对象(BLOB)
用DataReader检索二进制大对象(BLOB)时,应该将CommandBehavior.SequentialAccess传递给ExecuteReader方法调用。因为DataReader的默认行为是每次Read都将整行加载到内存,又因为BLOB值可能非常大,所以结果可能由于单个BLOB而使大量内存被用光。SequentialAccess将DataReader的行为设置为只加载请求的数据。然后还可以使用GetBytes或GetChars控制每次加载多少数据。
记住,使用SequentialAccess时,不能不按顺序访问DataReader返回的不同字段。也就是说,如果查询返回三列,其中第三列是BLOB,并且想访问前两列中的数据,就必须在访问BLOB数据之前先访问第一列的值,然后访问第二列的值。这是因为现在数据是顺序返回的,并且DataReader一旦读过该数据,该数据就不再可用。
使用命令
ADO.NET提供了几种命令执行的不同方法以及优化命令执行的不同选项。下面包括一些技巧,它们是关于选择最佳命令执行以及如何提高执行命令的性能。
使用OleDbCommand的最佳实践
不同.NET框架数据提供程序之间的命令执行被尽可能标准化了。但是,数据提供程序之间仍然存在差异。下面给出一些技巧,可微调用于OLE DB的.NET框架数据提供程序的命令执行。
1) 按照ODBC CALL语法使用CommandType.Text调用存储过程。使用CommandType.StoredProcedure只是秘密地生成ODBC CALL语法。
2) 一定要设置OleDbParameter的类型、大小(如果适用)、以及精度和范围(如果参数类型是numeric或decimal)。注意,如果不显式提供参数信息,OleDbCommand会为每个执行命令重新创建OLE DB参数访问器。
使用SqlCommand的最佳实践
使用SqlCommand执行存储过程的快速提示:如果调用存储过程,将SqlCommand的CommandType属性指定为StoredProcedure的CommandType。这样通过将该命令显式标识为存储过程,就不需要在执行之前分析命令。
使用Prepare方法
对于重复作用于数据源的参数化命令,Command.Prepare方法能提高性能。Prepare指示数据源为多次调用优化指定的命令。要想有效利用Prepare,需要彻底理解数据源是如何响应Prepare调用的。对于一些数据源(例如SQL Server 2000),命令是隐式优化的,不必调用Prepare。对于其他(例如SQL Server 7.0)数据源,Prepare会比较有效。
显式指定架构和元数据
只要用户没有指定元数据信息,ADO.NET的许多对象就会推断元数据信息。下面是一些示例:
1) DataAdapter.Fill方法,如果DataSet中没有表和列,DataAdapter.Fill方法会在DataSet中创建表和列。
2) CommandBuilder,它会为单表SELECT命令生成DataAdapter命令属性。
3) CommandBuilder.DeriveParameters,它会填充Command对象的Parameters集合。
但是,每次用到这些特性,都会有性能损失。建议将这些特性主要用于设计时和即席应用程序中。在可能的情况下,显式指定架构和元数据。其中包括在DataSet中定义表和列、定义DataAdapter的Command属性、以及为Command定义Parameter信息。
如果想返回像Count(*)、Sum(Price)或Avg(Quantity)的结果那样的单值,可以使用Command.ExecuteScalar。ExecuteScalar返回第一行第一列的值,将结果集作为标量值返回。因为单独一步就能完成,所以ExecuteScalar不仅简化了代码,还提高了性能;要是使用DataReader就需要两步才能完成(即,ExecuteReader+取值)。
使用不返回行的SQL语句时,例如修改数据(例如INSERT、UPDATE或DELETE)或仅返回输出参数或返回值,请使用ExecuteNonQuery。这避免了用于创建空DataReader的任何不必要处理。
测试Null
如果表(在数据库中)中的列允许为空,就不能测试参数值是否“等于”空。相反,需要写一个WHERE子句,测试列和参数是否都为空。下面的SQL语句返回一些行,它们的LastName列等于赋给@LastName参数的值,或者LastName列和@LastName参数都为空。
SELECT * FROM Customers WHERE ((LastName = @LastName) OR (LastName IS NULL AND @LastName IS NULL))
将Null作为参数值传递
对数据库的命令中,当将空值作为参数值发送时,不能使用null(Visual Basic .NET中为Nothing)。而需要使用DBNull.Value。例如:
'Visual Basic Dim param As SqlParameter = New SqlParameter("@Name", SqlDbType.NVarChar, 20) param.Value = DBNull.Value //C# SqlParameter param = new SqlParameter("@Name", SqlDbType.NVarChar, 20); param.Value = DBNull.Value;
执行事务
ADO.NET的事务模型已经更改。在ADO中,当调用StartTransaction时,调用之后的任何更新操作都被视为是事务的一部分。但是,在ADO.NET中,当调用Connection .BeginTransaction时,会返回一个Transaction对象,需要将它与Command的Transaction属性联系起来。这种设计可以在一个单一连接上执行多个根事务。如果未将Command.Transaction属性设置为一个针对相关的Connection而启动的Transaction,那么Command就会失败并引发异常。
即将发布的.NET框架将使您可以在现有的分布式事务中手动登记。这对于对象池方案来说很理想;在该方案中,一个池对象打开一次连接,但是在多个独立的事务中都涉及到该对象。.NET框架1.0发行版中这一功能并不可用。
使用连接
高性能应用程序与使用中的数据源保持最短时间的连接,并且利用性能增强技术,例如连接池。下面的主题提供一些技巧,有助于在使用ADO.NET连接到数据源时获得更好的性能。
连接池
用于ODBC的SQL Server、OLE DB和.NET框架数据提供程序隐式缓冲连接。通过在连接字符串中指定不同的属性值,可以控制连接池的行为。
用DataAdapter优化连接
DataAdapter的Fill和Update方法在连接关闭的情况下自动打开为相关命令属性指定的连接。如果Fill或Update方法打开了连接,Fill或Update将在操作完成的时候关闭它。为了获得最佳性能,仅在需要时将与数据库的连接保持为打开。同时,减少打开和关闭多操作连接的次数。
如果只执行单个的Fill或Update方法调用,建议允许Fill或Update方法隐式打开和关闭连接。如果对Fill和Update调用有很多,建议显式打开连接,调用Fill和Update,然后显式关闭连接。
另外,当执行事务时,显式地在开始事务之前打开连接,并在提交之后关闭连接。例如:
'Visual Basic Public Sub RunSqlTransaction(da As SqlDataAdapter, myConnection As SqlConnection, ds As DataSet) myConnection.Open() Dim myTrans As SqlTransaction = myConnection.BeginTransaction() myCommand.Transaction = myTrans Try da.Update(ds) myTrans.Commit() Console.WriteLine("Update successful.") Catch e As Exception Try myTrans.Rollback() Catch ex As SqlException If Not myTrans.Connection Is Nothing Then Console.WriteLine("An exception of type " & ex.GetType().ToString() & " was encountered while attempting to roll back the transaction.") End If End Try Console.WriteLine("An exception of type " & e.GetType().ToString() & " was encountered.") Console.WriteLine("Update failed.") End Try myConnection.Close() End Sub //C# public void RunSqlTransaction(SqlDataAdapter da, SqlConnection myConnection, DataSet ds) { myConnection.Open(); SqlTransaction myTrans = myConnection.BeginTransaction(); myCommand.Transaction = myTrans; try { da.Update(ds); myCommand.Transaction.Commit(); Console.WriteLine("Update successful."); } catch(Exception e) { try { myTrans.Rollback(); } catch (SqlException ex) { if (myTrans.Connection != null) { Console.WriteLine("An exception of type " + ex.GetType() +" was encountered while attempting to roll back the transaction."); } } Console.WriteLine(e.ToString()); Console.WriteLine("Update failed."); } myConnection.Close(); }
始终关闭Connection和DataReader
完成对Connection或DataReader对象的使用后,总是显式地关闭它们。尽管垃圾回收最终会清除对象并因此释放连接和其他托管资源,但垃圾回收仅在需要时执行。因此,确保任何宝贵的资源被显式释放仍然是您的责任。并且,没有显式关闭的Connections可能不会返回到池中。例如,一个超出作用范围却没有显式关闭的连接,只有当连接池大小达到最大并且连接仍然有效时,才会被返回到连接池中。
注不要在类的Finalize方法中对Connection、DataReader或任何其他托管对象调用Close或Dispose。最后完成的时候,仅释放类自己直接拥有的非托管资源。如果类没有任何非托管资源,就不要在类定义中包含Finalize方法。
在使用C#格式转换函数时,System Convert ToInt32将浮点类型转换为整形的时候,会自动进行四舍五入,l例如:
double dbVal = 3.14159;
int iVal = System.Conver.ToInt32(dbVal);
此处:iVal=3;
dbVal = 3.567;
iVal = System.Conver.ToInt32(dbVal);
此时:iVal=4;
而使用(int)强制转换的时候,则没有舍入规则,示例如下:
dbVal = 3.14159;
iVal = (int)dbVal;
此时:iVal = 3;
dbVal = 3.567;
iVal = (int)dbVal;
此时:iVal=3,没有进位。
如何在Visual Studio.net中让同一解决方案中包含多个不同类型的项目
1.通过“文件”-->“新建”-->“空白解决方案”建立一个新的解决方案MySolution1。
2.添加项目
“解决方案资源管理器”中,在“解决方案MySolution1”上右键,添加新项,选择“asp.net Web应用程序”项目作为启动项目,命名为Web。在其项目属性常规选项卡中,将“程序集名称”和“默认命名空间”都改成“MySolution1.Web”
同样的方法添加一个“类库”项目(可以作为业务逻辑层、数据访问层等),命名为ClassLibrary1。在其项目属性常规选项卡中,将“程序集名称”和“默认命名空间”都改成“MySolution1.ClassLibrary1”,目的是让这些项目在同一个命名空间下。将其生成的项目输出路径改到web项目的bin目录下。
如果还有多个项目都按上面的方法去做。
3.添加引用
将ClassLibrary1生成后,在Web项目的引用添加生成的.dll文件,添加时选择“项目”即可看到MySolution1.ClassLibrary1.dll文件
4.在Web项目中使用类
完成上面的步骤后就可以在web项目使用ClassLibrary1中的属性和方法了,当然只能使用那些公用的属性和方法。
今天学习了c#变量的初始化,参考了一些文章,自己总结了一下,便于加深记忆
c#中必需初始化变量并赋值,否则编译无法通过
一、 以下类别的变量自动初始化为它们的默认值:
1、 静态变量
例如:
public class A
{
public static int b;
}
在test.aspx内调用
Response.Write(A.b);
结果:0
2、 类实例的实例变量
例如:
public class A
{
public int b;
}
在test.aspx内调用
A a = new A();
Response.Write(a.b);
结果0
3、 数组元素
二、 变量的默认值取决于该变量的类型,并按下面确定
1、 对于值类型的变量,默认值与该值类型的默认构造函数所计算的值相同
2、 对于“引用类型”的变量,默认值为null
三、 以下类型的变量属于初始化未赋值变量
1、 初始未赋值结构变量的实例变量
2、 输出参数,包括结构实例构造函数的this变量。
3、 局部变量,在catch子句获foreach语句中声明的那些除外。