文章目录
写在前面
没有两三天.NET就要考试了,按照考试大纲自己梳理一遍( 临时抱佛脚 )
有些知识点大纲不考就没总结,面向考试编程
一、.NET Framework概述
NET Framework(又称 .NET 框架)是由微软开发,一个致力于敏捷软件开发、快速应用开发、 平台无关性和网络透明化的软件开发平台。
(框架:类似于Java的虚拟机,但在内部实现上与Java相比有本质区别,不是字节码,速度比Java快。语言:支持C#、C++、VB、J#)
.NET Framework组成
-
CLR
CTS和CLS是CLR的子集
CTS (通用类型系统)定义了在IL中的的数据类型
CLS (公共语言规范)CLR支持的语言功能的子集,包括几种面向对象的编程语言的通用功能
-
.NET Framework类库
①提供对系统功能的访问
②建立.NET应用程序,组件和控件的基础
③庞大的类库数量(170多个命名空间,上千个类)
④功能齐全,方便使用(对文件的基本操作、对网络的访问、安全控制、对图形的操作)
命名空间
命名空间既是Visual Studio 提供系统资源的分层组织方式,也是分层组织程序的方式。因此,命名空间有两种,一种是系统命名空间,一种是用户自定义命名空间。
系统命名空间使用using关键字导入,System是Visual Studio .NET中的最基本的命名空间,在创建项目时,Visual Studio 平台都会自动生成导入该命名空间,并且放在程序代码的起始处。
-
自定义命名空间
使用自定义命名空间可以避免类名相同冲突
-
嵌套命名空间
与Java的package相似
namespace City
{
namespace MySchool
{
namespace Class
{
class Student
{
// 此处编写代码
}
}
}
- 使用别名
using user = City.MySchool.Class;//定义别名
namespace MySchool
{
class Student
{
user.Student stu = new user.Student();//使用别名
}
}
- 框架类库中重要命名空间
命名空间 | 作用 |
---|---|
System.Data | 用于访问ADO.NET(使用DataTable、DataSet对象) |
System.IO | 用于操作文件 |
System.Windows.Forms | 用于开发Windows应用程序(使用MessageBox、Form对象) |
System.Collections.Generic | 可以使用泛型 |
System.Net | 可以对网络协议进行编程 |
System.Security | 提供系统的安全控制功能 |
System.Data.SqlClient | 用于访问ADO.NET(使用SqlConnection、 SqlCommand等对象) |
二、面向对象
面向对象的三大特性
- 封装
隐藏内部实现,稳定外部接口 - 继承
子类继承父类成员,实现代码复用 - 多态
不同子类对同一个消息作出不同的反映
类和对象
对象是人们要进行研究的任何事物
类描述一组相似对象的共性,即类的实例称为对象。
类的组成:
-
字段
就是一些定义的变量,通过访问修饰符(private和public等)分为私有成员和公有成员。 -
属性
即使set访问器和get访问器,这样就不直接访问类的数据,而是通过访问器访问(set/get),从而保护内部数据安全。 -
方法
方法是类或对象的行为。
类的方法
静态方法和实例方法
使用static关键字修饰的方法称为静态方法;使用实例对象调用的方法叫做实例方法。
静态方法 | 实例方法 |
---|---|
static 关键字 | 不需要static关键字 |
使用类名调用 | 使用实例对象调用 |
可以访问静态成员 | 可以直接访问静态成员 |
不可以直接访问实例成员 | 可以直接访问实例成员 |
不能直接调用实例方法 | 可以直接访问实例方法、静态方法 |
调用前初始化 | 实例化对象时初始化 |
重载
为了避免实现相近的功能,但参数类型、个数等不同而不得不重新命名方法,重载允许创建相同名字的方法,但这些方法有不同的参数列表。比如
class Add
{
public int Sum(int para1, int para2)
{…}
public int Sum(int para1, int para2,int para3)//参数个数不同
{…}
public string Sum(string para1, string para2)//参数类型不同
{…}
}
构造函数
构造函数是类中的一种特殊的方法。构造函数名与类名相同,不返回任何值;可初始化成员变量。配合着重载,我们可以用new关键字,实例化一个对象。
class Student
{
public Student() { }
public Student(string name, int age, string hobby)
{
this.Name = name;
this.Age = age;
this.Hobby = hobby;
}
}
//实例化
Student scofield = new Student();
Student zhang = new Student("张三", 20, "唱歌");
out和ref关键字
用于方法传参
类的继承和多态性
继承
一个类可以被另一个类继承,这个类就拥有他继承的类的所有成员,被继承的类称为基类/父类,继承基类的类称为派生类/子类,即满足is-a关系。
把共有属性放进父类,子类也可以有自己独有的属性和方法,减少代码冗余。继承还具有传递性和单根性。
public class Student:Person //通过:+基类名来声明
public class Teacher:Person
public Student(string name, Genders gender,
int age, string hobby, int popularity)
{
//父类属性
this.Name = name;
this.Age = age;
this.Gender = gender;
//学生类扩展的属性
this.Hobby = hobby;
this.Popularity = popularity;
}
public void SayHi()
{
//学生的SayHi
}
//调用
Student zhang = new Student(…);
zhang.SayHi();
base关键字
base关键字用来调用父类的属性、方法和构造函数
public Student(string name, Genders gender,
int age, string hobby, int popularity)
: base(name,age,gender) //调用父类的构造函数
{
//学生类扩展的属性
this.Hobby = hobby;
this.Popularity = popularity;
}
访问修饰符
访问权限
访问修饰符 | 类内部 | 子类 | 其他类 |
---|---|---|---|
public | 可以 | 可以 | 可以 |
private | 可以 | 不可以 | 不可以 |
protected | 可以 | 可以 | 不可以 |
多态
多态指不同对象收到相同消息时,会产生不同行为。都有相同的方法,但具体执行可能不一样,即满足has-a关系。
除了用前面的重载外,C#还可以通过关键字virtual在基类中定义虚方法,用override关键字在派生类中重载虚方法实现多态。
多态的代码实现前还需介绍抽象类。
抽象类和和抽象方法
抽象类用来列举一个类所需要的行为,抽象类不明确提供具体实现方法,抽象类必须由其子类实现它的抽象方法(除非子类也具有抽象性)。
用abstract关键字修饰,有抽象方法的类一定是抽象类,抽象类不能实例化,也不能是密封或静态的。
abstract class Person //基类
{
public abstract void SayHi();
}
//……
Person person = new Person(); //编译错误,不能实例化
//…… 派生类
public override void SayHi()//然后在派生类override重载方法
{
//…具体实现内容
}
虚方法
方法的重载是指类中有两个以上同名的方法,方法的签名(参数个数、类型和顺序)不同。
而虚方法的重载要求在派生类中重载方法时,方法签名以及返回类型都必须与基类中的虚方法一致。
简单来说,就是虚方法在基类提供了一个默认实现方法,子类可以使用该默认而不去重载方法,而抽象方法没有具体实现,子类必须重载。
//Person类中默认实现通用的SayHi()
public virtual void SayHi()
{
//…省略具体实现
}
虚方法和抽象方法区别
密封类
密封类是不能被继承的类,因此不能作为基类,也不能是抽象类,但是密封成员调用速度也会更快。用关键字sealed定义。
在基类的虚成员进行重写的派生类上,可以把方法、属性等成员声明为密封成员,目的是使成员所在类的派生类无法重载该成员。sealed关键字要位于override关键字前。
class Circle:Shape
{
//……
public sealed override void Draw()
{
//……
}
}
接口
接口是对一组可以实现的功能的定义,在其中定义了对象必须实现 的成员,通过其实现类来实现。接口不能直接实例化,不能包含成员的任何代码,只定义成员本身。通过interface关键字定义接口。
interface Drawable{ //定义一个接口
Void draw();
}
//在Circle类实现Drawable接口,即实现接口中声明的所有方法。
class Circle : Drawable{
Public void Draw(){
.....
}
}
比较常用的IComparable接口,用来排序。
public class Student:Person,IComparable //实现该接口
{
public int CompareTo(object obj) //实现CompareTo
{
if (!(obj is Student))
throw new Exception("只能与Student 对象比较");
Student other = obj as Student; //按姓名升序
return this.Name.CompareTo(other.Name);
}
}
接口和抽象类对比
枚举
枚举是一组描述性的名称,枚举定义一组有限的值,不能包含方法,对可能的值进行约束。枚举可以用描述性的名称表示值,使用时无需了解它的构成。
访问修饰符 enum 枚举名 {值1,值2… }
public enum Test
{
S1 ,S2,Y2
}
Console.WriteLine("S2的值是{0}.", Test.S2.ToString());//枚举转换为字符串
(Test)(Enum.Parse(typeof(Accp),"S2");//字符串转换为枚举
结构
结构中有属性,也可以有方法
访问修饰符 struct 结构名
{
定义结构成员
}
//比如
public struct StructStudent
{
public string Name;
public int Age;
public string Hobby;
public int Popularity;
public void SayHi()
{
// ….
}
}
//调用
StructStudent myStu;//不能用new
myStu.Age = 20;//赋值结构成员
myStu.Gender = Genders.Female;
myStu.Hobby = "唱歌";
myStu.Name = "张三";
myStu.Popularity = 100;
myStu.SayHi();
结构和类异同
三、集合与泛型
ArrayList
ArrayList是一个可动态维护长度的集合。
注意结构是值类型,不是引用类型,用ArrayList遍历修改失败。
//初始化
using System.Collections; //引入命名空间
//定义
ArrayList students = new ArrayList(); //实例化一个对象
ArrayList Teachers = new ArrayList(5); //可以指定长度
//添加
Student scofield = new Student("Scofield", Genders.Male, 25, "唱歌");
students.Add(scofield); //调用add()
//访问:(类型) ArrayList[index] //按指定索引(下标)取得对象
Student stu1 = (Student)students[0];//从0开始,注意类型转换
stu1.SayHi();
//删除
//ArrayList.Remove(对象名) //删除指定对象名的对象
//ArrayList.RemoveAt(index) //删除指定索引的对象
//ArrayList.Clear() //清除集合内的所有元素
students.RemoveAt(0); //通过索引删除对象
students.Remove(zhang); //指定删除对象
Student leave = (Student)students[0];//取得删除后第一个对象
leave.SayHi(); //删除后的索引会自动调整
//遍历
for (int i = 0; i < students.Count; i++)
{
Student stuFor = (Student)students[i];
Console.WriteLine(stuFor.Name);
}
foreach (Object stuo in students)
{
Student stuForeach = (Student)stuo;
Console.WriteLine(stuForeach.Name);
}
HashTable
HashTable即哈希表,根据键(Key)可以查找到相应的值 (Value),ArrayList 每个元素对应一个索引。
//添加
students.Add(scofield.Name,scofield); //(key,value)
//访问
Student stu2 = (Student)students[“张三"];//通过key获取元素(注意类型转换)
stu2.SayHi();
//删除
students.Remove(“张三"); //通过key删除元素
//遍历
foreach (Object stuo in students.Values)
{ //不能遍历整个对象,而是遍历Values
Student stu = (Student)stuo;
Console.WriteLine(stu.Name);
}
foreach (string name in students.Keys)
{ //可以遍历keys
Console.WriteLine(name);
}
List< T >
ArrayList对象存储不易控制,类型转换容易出错,比如向students添加一个teacher的对象,所以使用泛型集合来约束集合内的元素类型 ,典型泛型集合List< T >,Dictionary< K,V > <t>,<k,v>表示该泛型集合中的元素类型
操作和ArrayList相似,不过无需类型转换。
using System.Collections.Generic //命名空间
//定义
List<Student> students = new List<Student>();//只能保存student对象
//添加
Student scofield = new Student("Scofield", Genders.Male, 25, "唱歌");
students.Add(scofield);
Teacher jacky = new Teacher(“王五", 4);
students.Add(jacky ); //报错
//访问
Student stu1 = students[2]; //使用索引访问,无需类型转换
stu1.SayHi();
//删除
Students.RemoveAt(0); //利用索引删除
//遍历
foreach (Student stu in students)
{ //无需类型转换
Console.WriteLine(stu.Name);
}
List< T >和ArrayList的异同点
Dictionary< K,V >
同样的,Dictionary< K,V >是对应HashTable的泛型集合。
//定义
//Key存储string类型,Value存储Student类型
Dictionary<string,Student> students = new Dictionary<string,Student>();
//添加
students.Add(scofield.Name, scofield);
students.Add(jacky.Name,jacky);//teacher报错
//访问
Student stu2 = students[“张三"];
//删除
students.Remove(“张三");
//遍历
foreach (Student student in students.Values)
{
Console.WriteLine(student.Name);
}
Dictionary< K,V >t和HashTable的异同点
四、XML、文件读写与序列化
序列化的含义
序列化是将对象的状态存储到特定存储介质中的过程,主要目的是保存对象的状态以便以后需要的时候使用。与其相反的过程叫做反序列化。这两个过程结合起来使得数据能够被轻松存储和使用。
命名空间
using System.Runtime.Serialization.Formatters.Binary;
操作步骤如下:
- 声明可序列化对象
加上标识[Serializable]后,就能将类序列化 - 序列化对象
把对象格式化为二进制格式,并把结果写入一个流(文件流/内存流/网络流)。调用BinaryFormatter的Serialize()方法进行序列化 - 反序列化对象
打开流进行读取,把流反序列化为对象。调用BinaryFormatter的Deserialize()方法。
FileMode和FileAccess
FileStream对象表示在磁盘或网络路径上指向文件的流,其提供了在文件中读/写字节的方法。
public FileStream(string path,FileMode mpde)
public FileStream(string path,FileMode mpde,FileAccess access)
public FileStream(string path,FileMode mpde,FileAccess access,FileShare share)
参数说明:
- 参数path是一个字符串,指定文件路径
- 参数mode用于确定如何打开或创建文件,控制对文件执行改写、建立、打开等操作,取值如下:
值 | 说明 |
---|---|
Append | 打开现有文件或创建新文件 |
Create | 创建新文件,若已存在则删除旧文件 |
CreateNew | 创建新文件,若已存在则异常 |
Open | 打开文件,若不存在则异常 |
OpenOrCreate | 打开文件,若不存在则创建新文件 |
Truncate | 打开文件并清除其内容,若不存在则异常 |
- 参数access用于确定FileStream对象访问文件的方式,取值如下:
值 | 说明 |
---|---|
Read | 只读 |
Write | 只写 |
ReadWrite | 读写 |
- 参数share用于确定文件如何由进程共享
应用实例:
FileStream myfs = new FileStream( 'D:\', FileMode.Create); //创建文件流
StreamWriter mySw = new StreamWriter(myfs); //创建写入器
mySw.Write(content); //写入方法
//mySw.WriteLine(content); //写入一行数据
mySw.Close(); //关闭写入器
StreamReader mySr = new StreamReader(myfs); //创建读取器
content = mySr.ReadToEnd(); //读取到文件末尾
//content = mySr.ReadLine(); //读取一行
mySr.Close(); //关闭读取器
XmlDocument
XML(可扩展标记性语言)是一套定义语义标记的规则,这些标记将文档分成许多不见并对这些不见加以标识。XmlDocument对象表示XML整个文档。
属性和方法 | 说明 |
---|---|
DocumentElement 属性 | 获取根节点 |
ChildNodes 属性 | 获取所有子节点 |
Load()方法 | 读取整个XML的结构 |
XmlDocument myXml = new XmlDocument();
myXml.Load("Student.xml"); //读取xml文件
XmlNode student = myXml.DocumentElement; //获取根节点
foreach (XmlNode node in student.ChildNodes ) //获取当前节点所有子节点
{
switch (node.Name) //当前节点名字
{
case "Name":
Console.WriteLine("姓名:{0}",node.InnerText);//当前节点值
break;
// …
}
}
代码阅读-RssFeed
/// <summary>
/// 填充文章列表
/// </summary>
public void FillArticles()
{
articles[0] = new Article("标题1","网址1");//实例化Article并填入articles数组
articles[1] = new Article("标题2", "网址2");
articles[2] = new Article("标题3","网址3");
}
五、绘图
绘图的基本步骤
- 建立关联的Graphics对象
- 建立画笔对象
- 建立画刷对象
- 使用画笔绘制图形
- 使用画刷填充图形内部
Graphics
Graphics类提供一些方法绘制各种图形。Graphics类是密封类,不能有派生类。
Pen
Pen类对象指定绘制图形的外轮廓线的宽度和颜色。
Pen对象常用属性:
- Color:设置Pen的颜色。
- Width:设置Pen的宽度。
- DashStyle:定义笔的画线样式,是枚举类型的值
设置值 | 说明 |
---|---|
Dahs | 虚线 |
DashDot | 点画线 |
DashDotDot | 双点画线 |
Dot | 点线 |
Solid | 实线 |
Cutstom | 用户自定义 |
- DashCap:设置虚线两端的外端
- StartCap和EndCap:设置设置直线起点和终点的帽样式
设置值 | 说明 |
---|---|
ArrowAnchor 箭头状锚头帽 | |
DiamondAnchor | 菱形锚头帽 |
Flat | 平线帽 |
NoAnchor | 没有锚 |
RoundAnchor | 圆锚头帽 |
SquareAchor | 方锚头帽 |
Square | 方线帽 |
Round | 圆线帽 |
Triangle | 三角线帽 |
Custom | 自定义 |
public Pen(Color color); //创建某一颜色的Pen对象
public Pen(Color color,float width); //创建Pen并设置画笔宽度和颜色
public Pen(Brush brush); //创建某一刷子样式的Pen
public Pen(Brush,float width); //创建某一刷子样式的Pen并设置相应宽度
Brush
Brush类对象指定填充封闭图形内部的样式和颜色。命名空间System.Drawing。
GDI+系统提供了几个预定义画刷类,包括:
- 单色画刷:命名空间System.Drawing
SolidBrush 刷子=new SolidBrush(颜色)
SolidBrush reBrush=new SolidBrush(Color.Blue);
- 阴影画刷:后面画刷在命名空间System.Drawing.Drawing2D中定义。
HatchBrush 刷子=new HatchBrush(style,foreColor,bakcColor)
HatchBrush HB=new HatchBrush(Hatch.Cross,Color.Cyan,Color.Chocolate);
- 纹理(图像)画刷:
Image img;
img=Image.FormFile(@"路径\图形文件名.bmp");
TextureBrush txtBrush=new TextureBrush(img,style);
- 渐变画刷:
两个颜色或多个颜色线性渐变画刷:
LinearGradientBrush 刷子 =new LinearGradientBrush(point1,point2,point3,point4)
PathGradientBrush:使用路径定义刷子形状的复杂渐变画刷。
鼠标事件
事件名 | 描述 |
---|---|
MouseEnter | 鼠标指针移入控件时触发此事件 |
MouseMove | 移动鼠标光标时触发此事件 |
MouseHover | 鼠标指针悬停在控件上时触发此事件 |
MouseDown | 鼠标位于控件上并按下鼠标键时触发此事件 |
MouseUp | 鼠标位于控件上并释放鼠标键时触发该事件 |
MouseLeave | 鼠标指针移出控件时触发此事件 |
private void Form1_MouseDown(object sebder,MouseEventArgs e)
{
//……
}
鼠标位置由参数e的X和Y属性确定,都是int类型,即e.X和e.Y来获取XY坐标。
鼠标按钮状态有参数e的Button属性确定,该属性是枚举类型,其取值为:Left(按下鼠标左按钮)、Middle(按下鼠标中间按钮)、Right(按下鼠标右按钮)和None(未按下鼠标按钮)。
Paint事件
当发生窗体最小化后再最大化、菜单被打开再关闭或打开对话框再关闭等情况,用户区内容可能被破坏。操作系统不保存被破坏的用户区内容,而是由应用程序自己恢复被破坏的用户区内容。
当应用程序窗口用户区内容被破坏后需恢复时,Windows操作系统向应用程序发送Paint事件,应用程序应把在窗口用户区输出数据的语句放在Paint事件处理函数中,应用程序响应Paint事件,能在事件处理函数中调用这些在窗口用户区输出数据的语句恢复被破坏的内容。
Form类窗体不能自动响应Paint事件,程序员必须生成Paint事件处理函数。
代码阅读-FormPaintDemo
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace FormPaintDemo
{
public partial class Form1 : Form
{
private bool mark = false;//表示鼠标左键是否按下,如按下鼠标再移动将画曲线
private Point point;//记录画下一条很短线段的起始点。
private List<Point> Point_List; //用来记录1条曲线的所有点。
private List<List<Point>> Line_List;
Pen pen1 = new Pen(Color.Red, (float)3.0);
Graphics g;
public Form1()
{
InitializeComponent();
Line_List = new List<List<Point>>();
g = this.CreateGraphics();
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point_List = new List<Point>(); //建立数组,记录1条曲线的所有点
point.X = e.X;
point.Y = e.Y;
mark = true;
Point_List.Add(point); //记录曲线起点的坐标
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (mark)
{
g.DrawLine(pen1, point.X, point.Y, e.X, e.Y);
point.X = e.X;
point.Y = e.Y;
Point_List.Add(point); //记录曲线中其它点的坐标
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
mark = false;
Line_List.Add(Point_List);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
Point p1, p2;
foreach (List<Point> pl in Line_List)//取出每条线
{
for (int k = 0; k < pl.Count - 1; k++)//重画每条线的点
{
p1 = pl[k];
p2 = pl[k + 1];
g.DrawLine(pen1, p1, p2);
}
}
}
}
}
六、ADO.NET
SqlConnection
Connection对象用于打开数据库连接,参数说明:
参数 | 说明 |
---|---|
server | 所连接数据库服务器名称,本地是local |
database | 所需访问数据库名称 |
uid | 登录数据库所需用户名 |
pwd | 登录数据库所需密码 |
Connect Timeout | 连接超时时间 |
integrated security | 集成安全性,可以设置为: True, false, yes, no,sspi(即true),true用Windows身份验证,否则SQL Sever身份验证 |
SqlCommand
连接到数据库后,可以用Command对象对数据库进行操作。
常用属性:
- CommandText
获取或设置要对数据源执行的T-SQL语句、表名或存储过程名 - CommandType
获取或设置一个值,该值指示如何解释CommandText属性。
为Text时(默认),设置为要执行的SQL文本命令;
为StoredProcedure时,设置为要访问的存储过程名称;
为TableDirect时,设置为要访问的表的名称。 - Parameters
向存储过程传递参数,指定属性值。
常用方法:
- ExecuteNonQuery
对连接执行T-SQL语句并返回受影响的行数,多用于执行增删改命令。 - ExecuteReader
用于查询操作,通过DataReader对象的Read方法逐行读取。
DataReader
从数据库中检索只读、只进的数据流。
常用属性和方法:
- FieldCount:获取当前行的列数
- HasRows:获取一个值,指示是否包含一行或多行
- IsClosed:指示是否已关闭
- Item[Int32]:以列的索引值的方式获取记录中某个字段的数据
- Item[String]:以列的名称方式获取记录中某个字段的数据
- Read:获取一行记录
- Close:关闭该对象
代码阅读-CommandStoreProcedure01
using System;
using System.Data;
using System.Data.SqlClient;
namespace CommadnDemo
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
//创建一个Connection对象来连接数据库
//连接数据库服务器名:jmucj;数据库:northwind;用户名:sa;密码:123
SqlConnection cn =new SqlConnection("server=jmucj;database=northwind;uid=sa;pwd=123");
SqlCommand cmd=new SqlCommand();//创建Command对象来操作数据库
cmd.Connection=cn;
cn.Open();//打开连接
cmd.CommandType=CommandType.StoredProcedure;//调用存储过程
cmd.CommandText="getproductlist";//存储过程名
cmd.Parameters.Add(new SqlParameter("@id",SqlDbType.Int,4));//传参@id=4,整型
cmd.Parameters["@id"].Direction = ParameterDirection.Input;//输入参数
int id=int.Parse(Console.ReadLine());//从控制台读取id
cmd.Parameters["@id"].Value=id;//赋值
SqlDataReader reader=cmd.ExecuteReader();//创建Reader对象来读取
while(reader.Read()) //遍历打印读取结果(第一列的字符串和第三列的32w)
{
Console.WriteLine(reader.GetString(1)+" "+reader.GetInt32(3).ToString());
}
cn.Close();//关闭连接
Console.ReadLine();
}
}
}
DataSet
是数据的一种内存驻留表示形式,无论它包含的数据来自什么数据源,都会提供一致的关系编程模型。
- DataTable:表示内存中的一个表
- Data Row:表示DataTable中的一行数据
- DaraColum:表示DataTable中的列的架构
- DataRelation:可以将DataTable当作数据库的内存副本
SqlDataAdapter
充当DataSet和数据源之间用于检索和保存数据的桥梁,能够检索和保存数据。DataAdapter用来从数据库中读取数据的Command对象存储在DataAdapter对象的SelectCommand属性中。
- SelectCommand:引用从数据源中检索行的Command对象
- Insertcommand:引用将插入的行从DataSet写入数据源的Command对象
- UpdateCommand:引用将修改的行从DataSet写入数据源的Command对象
- DeleteCommand:引用从数据源中删除行的Command对象
- Fill:使用此方法,从数据源中增加或刷新行,并这些行放到DataSet表中
- Update:使用此方法,将DataSet表中的更改传送到相应的数据源中
代码阅读-DataRelationCS01
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace DataRelationCS01
{
class Program
{
static void Main(string[] args)
{
DataSet ds = new DataSet();
DataColumn col;
DataTable dt = new DataTable("Customers");//新建Customers表
ds.Tables.Add(dt);//添加到内存数据源
col = ds.Tables["Customers"].Columns.Add("CustomerID", typeof(string));
col.MaxLength = 5; //设置一列值为CustomerID,字符串类型,最大长度为5
col = ds.Tables["Customers"].Columns.Add("CompanyName", typeof(string));
col.MaxLength = 40; //设置一列值为CompanyName,字符串类型,最大长度为40
col = ds.Tables["Customers"].Columns.Add("ContactName", typeof(string));
col.MaxLength = 30; //设置一列值为ContactName,字符串类型,最大长度为30
col = ds.Tables["Customers"].Columns.Add("Phone", typeof(string));
col.MaxLength = 24; //设置一列值为Phone,字符串类型,最大长度为30
ds.Tables["Customers"].PrimaryKey = new DataColumn[] {ds.Tables["Customers"].Columns["CustomerID"]};
//设置Customers表主键为CustomerID
DataRow row;
row = ds.Tables["Customers"].NewRow();//新建一行并赋值
row[0] = "a0";
row[1] = "IBM";
row[2] = "Michael";
row[3] = "1234";
ds.Tables["Customers"].Rows.Add(row);
row = ds.Tables["Customers"].NewRow();
row[0] = "b0";
row[1] = "DELL";
row[2] = "David";
row[3] = "4567";
ds.Tables["Customers"].Rows.Add(row);
dt = new DataTable("Orders");//又新建一个Orders表,大同小异
ds.Tables.Add(dt);
col = ds.Tables["Orders"].Columns.Add("OrderID", typeof(int));
col.AutoIncrement = true; //设置自增长
col.AutoIncrementSeed = 1;
col.AutoIncrementStep = 1;
col.ReadOnly = true; //设置只读
col = ds.Tables["Orders"].Columns.Add("CustomerID", typeof(string));
col.AllowDBNull = false; //不允许为空
col.MaxLength = 5;
ds.Tables["Orders"].Columns.Add("EmployeeID", typeof(int));
ds.Tables["Orders"].Columns.Add("OrderDate", typeof(DateTime));
ds.Tables["Orders"].PrimaryKey = new DataColumn[] {ds.Tables["Orders"].Columns["OrderID"]};
row = ds.Tables["Orders"].NewRow();
row[1] = "a0";
row[2] = 3;
DateTime mydatetime;
mydatetime = new DateTime(2005, 1, 8);
row[3] = mydatetime;
ds.Tables["Orders"].Rows.Add(row);
row = ds.Tables["Orders"].NewRow();
row[1] = "b0";
row[2] = 4;
mydatetime = new DateTime(2005, 4, 13);
row[3] = mydatetime;
ds.Tables["Orders"].Rows.Add(row);
DataRelation rel;
rel = new DataRelation("CustomersOrders", //把两个表通过CustomerID联系起来
ds.Tables["Customers"].Columns["CustomerID"],
ds.Tables["Orders"].Columns["CustomerID"]);
ds.Relations.Add(rel);
Console.WriteLine(ds.Relations.Count); //联系的数量(1)
Console.WriteLine(ds.Relations[0].RelationName);//第一个联系的名字(CustomersOrders)
Console.WriteLine(ds.Tables.Count);//表的数量(2)
Console.WriteLine(ds.Tables[0].PrimaryKey.Length);//第一个表的主键长度(1)
Console.WriteLine(ds.Tables[0].Constraints.Count);//第一个表的约束的数量(1)
Console.WriteLine(ds.Tables[0].Columns.Count);//第一个表列数(4)
//select CustomerID,CompanyName,OrderID,OrderDate where Customers.CustomerID=Orders.CustomerID
foreach (DataRow dr1 in ds.Tables["Customers"].Rows)
{
Console.Write(dr1["CustomerID"] + "--" + dr1["CompanyName"]);
foreach (DataRow dr2 in dr1.GetChildRows("CustomersOrders"))
Console.WriteLine(" " + dr2["OrderID"] + " " + dr2["OrderDate"]);
}
Console.WriteLine("----******************************************----");
foreach (DataRow dr2 in ds.Tables["Orders"].Rows)
{
Console.Write(dr2["OrderID"] + " " + dr2["OrderDate"]);
DataRow dr1 = dr2.GetParentRow(rel);
Console.WriteLine(" " + dr1["CustomerID"] + "-" + dr1["CompanyName"]);
}
ds.WriteXml(@"C:\a.xml");// 写入xml
DataSet newds = new DataSet();
newds.ReadXml(@"C:\a.xml");//读取该xml
Console.WriteLine("*********************");
Console.WriteLine("*********************");
Console.WriteLine("*********************");
Console.WriteLine(newds.Tables.Count);//表的数量(运行结果与前面一致)
Console.WriteLine(newds.Tables[0].Rows.Count);//第一个表的行数
Console.WriteLine(newds.Tables[0].Columns.Count);//第一个表的列数
Console.ReadLine();
}
}
}
代码阅读-DataAdapterDemo03
using System;
using System.Data;
using System.Data.SqlClient;
namespace DataAdapterDemo03
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
//连接数据库:本地服务器;数据库名:northwind;集成安全用Windows身份验证
SqlConnection cn =new SqlConnection("server=localhost;database=northwind;integrated security=sspi");
SqlDataAdapter da1=new SqlDataAdapter();//新建DataAdapter对象
SqlCommand selectcmd1=new SqlCommand("select * from category",cn);//新建查询语句
da1.SelectCommand=selectcmd1;//加到DataAdapter的SelectCommand对象
SqlCommand selectcmd2=new SqlCommand();//同上
selectcmd2.Connection=cn;
selectcmd2.CommandType=CommandType.Text;
selectcmd2.CommandText = "select * from products";
SqlDataAdapter da2=new SqlDataAdapter(selectcmd2);
DataSet ds=new DataSet();//新建DataSet对象
cn.Open();//开启连接
da1.Fill(ds,"category");//添加刷新category表的行,并加入到ds中
da2.Fill(ds, "products");
cn.Close();//关闭连接
Console.WriteLine("Table Count: "+ds.Tables.Count.ToString());//输出ds中表的数量
while (true)
{
Console.WriteLine("请选择输入1--2");
string i=Console.ReadLine();
if (i=="1")//如果控制台输入1
{
foreach(DataRow dr in ds.Tables["category"].Rows)//打印category表所有信息
{
int j=0;
for (j=0;j<ds.Tables["category"].Columns.Count-1;j++)
{
Console.Write(dr[j].ToString()+" "+"||");
}
Console.WriteLine();
}
}
else if(i=="2")//如果控制台输入2
{
foreach(DataRow dr in ds.Tables["products"].Rows)//打印products表所有信息
{
int j=0;
for (j=0;j<ds.Tables["products"].Columns.Count-1;j++)
{
Console.Write(dr[j].ToString()+" "+"||");
}
Console.WriteLine();
}
}
}
Console.ReadLine();
}
}
}
原创不易,请勿转载(
本不富裕的访问量雪上加霜)
博主首页:https://blog.csdn.net/qq_45034708
如果文章对你有帮助,记得关注点赞收藏❤
注意:本文归作者所有,未经作者允许,不得转载