实体框架,简单实体框架

简单实体框架实体框架 今天要说的实体框架并不是 ADO.NET EntityFramework,而是利用特性与反射技术自己来搭建一个简单的实体框架。在来讲之前先说些题外话,我们知道要想使一个项目有更好的健壮性、可移植型,是要将项目分层,不管是c/s,还是b/s框架一般都是三层架构,数据处理层(DAL)、业务逻辑层(BLL)、界面显示层(USL或者UI)。当然根据项目的业务流程可能分个七八层也是常有的事。今天主要讲的是在数据处理层是怎样实现实体架构的。
l 言归正传,现在开始构建框架,首先建立数据库,就做一个学生选课信息系统(StudentManage),包括三张表,一个学生信息表(Students),一个课程表(CourseS),一个选课表(SCs),它们之间的关系如下图所示:
简单实体框架实体框架
好了,数据库建好后,我们到程序中去进行操作,新建一个winform项目
看一下需要创建的类:
简单实体框架实体框架
先来构建特性类
///
/// 表特性类
///

[AttributeUsage(AttributeTargets.Class)]//可以对类应用特性
public class TableAttribute:Attribute
{
///
/// 表名
///

public string TableName
{
get;
set;
}
}
[AttributeUsage(AttributeTargets.Property)]//可以对属性应用特性
public class FieldAttribute : Attribute
{
///
/// 字段名
///

public string FieldName
{
get;
set;
}
///
/// 字段类型
///

public SqlDbType FieldType
{
get;
set;
}
///
/// 是不是主键
///

public bool IsPrimaryKey
{
get;
set;
}
///
/// 是否为空
///

public bool IsNull
{
get;
set;
}
///
/// 是否是自动增长
///

public bool IsIdentity
{
get;
set;
}
}
在构建实体类(和表是对应着的):
///
/// 空接口,实体类的父类
///

public class IEntity
{
}
//学生类
[Table(TableName = "Students")]//表名(注意TableAttribute可以简写为Table)
public class Student:IEntity
{
[Field(FieldName="StudentID",FieldType=SqlDbType.NVarChar,IsPrimaryKey=true)]//字段特性
public string StudentID
{
get;
set;
}
[Field(FieldName="StudentName",FieldType=SqlDbType.NVarChar)]
public string StudentName
{
get;
set;
}
[Field(FieldName="Sex",FieldType=SqlDbType.NVarChar)]
public string Sex
{
get;
set;
}
[Field(FieldName="Age",FieldType=SqlDbType.TinyInt)]
public int Age
{
get;
set;
}
//课程类
[Table(TableName="Courses")]
public class Course:IEntity
{
[Field(FieldName="CourseID",FieldType=SqlDbType.Int,IsPrimaryKey=true,IsIdentity=true)]
public int CourseID
{
get;
set;
}
[Field(FieldName = "CourseName", FieldType = SqlDbType.NVarChar)]
public string CourseName
{
get;
set;
}
}
//选课实体类
[Table(TableName="SCs")]
public class SC:IEntity
{
[Field(FieldName="StudentID",FieldType=SqlDbType.NVarChar,IsPrimaryKey=true)]
public string StudentID
{
get;
set;
}
[Field(FieldName = "CourseID", FieldType = SqlDbType.Int, IsPrimaryKey = true)]
public int CourseID
{
get;
set;
}
}
好了,实体类构建完成后,我们就来构建实体操作类:
public class EntityOPT
{
string constr;//连接字符串
SqlConnection con;//数据库连接
///
/// 数据初始化
///

public EntityOPT()
{
constr = "server=.;database=StudentManage;uid=sa;pwd=sa"; ;
con = new SqlConnection(constr);
}
///
/// 获得表名
///

///
///
string GetTableName(Type type)
{
return ((TableAttribute)type.GetCustomAttributes(true)[0]).TableName;//给类只加了一个自定义特性
}
public List QueryAll() where T : IEntity//由于不知道前台会传哪个实体类,所以用泛型
{
try
{
Type type = typeof(T);//得到类型
List entitys = new List();//实体集合
string sql = "select *from " + GetTableName(type);//获得表名,拼接sql语句
SqlDataAdapter da = new SqlDataAdapter(sql, constr);
DataTable dt = new DataTable();
da.Fill(dt);//向DataTable中填充数据
foreach (DataRow row in dt.Rows)//遍历所有行
{
ConstructorInfo conInfo = type.GetConstructor(new Type[0]);//得到构造函数
object obj = conInfo.Invoke(null);//实例化对象
foreach (PropertyInfo pi in type.GetProperties())//得到所有属性
{
foreach (object ob in pi.GetCustomAttributes(true))//遍历字段所有特性
{
if (ob is FieldAttribute)
{
string fieldname = (ob as FieldAttribute).FieldName;//得到表中字段的名字
pi.SetValue(obj, row[fieldname], null);//给实体类属性赋值
break;
}
}
}
entitys.Add((T)obj);
}
return entitys;
}
catch (Exception ex)
{
throw new Exception("数据层查询所有数据发生异常:" + ex.Message);
}
}
///
/// 插入数据
///

///
///
public bool InsertEntity(IEntity entity)
{
try
{
Type type = entity.GetType();
List pars = new List();//sql参数集合
string sql = "insert into " + GetTableName(type) + " values(";
foreach (PropertyInfo pi in type.GetProperties())//遍历类的所有属性
{
foreach (object obj in pi.GetCustomAttributes(true))//遍历属性的特性
{
if (obj is FieldAttribute && !(obj as FieldAttribute).IsIdentity)//有些主键是不自动增长的,如学号
{
string par = "@" + (obj as FieldAttribute).FieldName;
sql += par + ",";//拼接sql语句
SqlParameter sp = new SqlParameter(par, (obj as FieldAttribute).FieldType);
sp.Value = pi.GetValue(entity, null);
pars.Add(sp);
break;
}
}
}
sql = sql.TrimEnd(',') + ")";//去掉多余的逗号
return SaveChange(sql, pars);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
///
/// 删除数据
///

///
///
public bool DeleteEntity(IEntity entity)
{
try
{
Type type = entity.GetType();
List sps = new List();
string sql = "delete " + GetTableName(type) + " where ";
foreach (PropertyInfo pi in type.GetProperties())
{
foreach (object obj in pi.GetCustomAttributes(true))
{
if (obj is FieldAttribute && (obj as FieldAttribute).IsPrimaryKey)
{
FieldAttribute fa = obj as FieldAttribute;
sql += fa.FieldName + "=@" + fa.FieldName+" and ";//可能会是联合主键
SqlParameter sp = new SqlParameter("@" + fa.FieldName, fa.FieldType);
sp.Value = pi.GetValue(entity, null);
sps.Add(sp);
break;
}
}
}
sql = sql.Substring(0, sql.Length - 4);
return SaveChange(sql,sps);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
///
/// 更新数据
///

///
///
public bool UpdateEntity(IEntity entity)
{
try
{
Type type = entity.GetType();
List pars = new List();
string sql = "update " + GetTableName(type) + " set ";
string where = " where ";
foreach (PropertyInfo pi in type.GetProperties())
{
foreach (object obj in pi.GetCustomAttributes(true))
{
if (obj is FieldAttribute)
{
FieldAttribute fa = obj as FieldAttribute;
if (fa.IsPrimaryKey)
{
where += fa.FieldName + "=@" + fa.FieldName;
SqlParameter sp = new SqlParameter("@" + fa.FieldName, fa.FieldType);
sp.Value = pi.GetValue(entity, null);
pars.Add(sp);
}
else
{
sql += fa.FieldName + "=@" + fa.FieldName + ",";
SqlParameter sp = new SqlParameter("@" + fa.FieldName, fa.FieldType);
sp.Value = pi.GetValue(entity, null);
pars.Add(sp);
}
break;
}
}
}
sql = sql.TrimEnd(',') + where;
return SaveChange(sql, pars);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
///
/// 向数据库提交数据
///

///
///
///
bool SaveChange(string sql, List pars)
{
try
{
SqlCommand cmd = new SqlCommand(sql, con);
foreach (SqlParameter par in pars)
{
cmd.Parameters.Add(par);
}
con.Open();
int count = cmd.ExecuteNonQuery();
if (count > 0)
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
con.Close();
}
}
}
好了,到这一步,一个简单的实体框架算是构建完成,下面来测试。
先做一个界面:
简单实体框架实体框架
四个button控件,一个dataGridView控件。
先来做学生的添加:
Student student = new Student();
student.StudentID = "09040401036";
student.StudentName = "张三";
student.Age = 18;
student.Sex = "男";
if (entityopt.InsertEntity(student))
{
MessageBox.Show("添加成功!");
}
else
{
MessageBox.Show("添加失败!");
}
查询操作:
private void button4_Click(object sender, EventArgs e)
{
dataGridView1.DataSource = entityopt.QueryAll();
}
单击添加并查询:
简单实体框架实体框架
添加成功。
来做修改,把名字改为李四:
Student student = new Student();
student.StudentID = "09040401036";
student.StudentName = "李四";
student.Age = 18;
student.Sex = "男";
if (entityopt.UpdateEntity(student))
{
MessageBox.Show("修改成功!");
}
else
{
MessageBox.Show("修改失败!");
}
单击修改,并查询:
简单实体框架实体框架
修改成功。
删除刚才的学生信息:
Student student = new Student();
student.StudentID = "09040401036";
if (entityopt.DeleteEntity(student))
{
MessageBox.Show("删除成功!");
}
else
{
MessageBox.Show("删除失败!");
}
删除并查询:
简单实体框架实体框架
删除成功。
下面在对课程操作,首先添加课程:
Course course = new Course();
course.CourseName = "C#";
if (entityopt.InsertEntity(course))
{
MessageBox.Show("添加成功!");
}
else
{
MessageBox.Show("添加失败!");
}
查询操作:
dataGridView1.DataSource = entityopt.QueryAll();
点击添加,然后查询,结果:
简单实体框架实体框架
我们看到课程也添加成功了,在做修改:
Course course = new Course();
course.CourseID = 1;
course.CourseName = "asp.net";
if (entityopt.UpdateEntity(course))
{
MessageBox.Show("修改成功!");
}
else
{
MessageBox.Show("修改失败!");
}
点击修改,并查询,结果:
简单实体框架实体框架
课程也能修改成功!
再来删除!
Course course = new Course();
course.CourseID = 1;
if (entityopt.DeleteEntity(course))
{
MessageBox.Show("删除成功!");
}
else
{
MessageBox.Show("删除失败!");
}
看一下运行结果:
简单实体框架实体框架
删除成功!
好了,到这一步我们发现实体框架构建成功,并能运行。不过注意了,如果要是做选课的修改时,不能直接调用修改方法,因为它是联合主键,应该先删除在添加,其实修改本本身就是先删除后添加的过程。
好,今天讲的东西虽然是简单实体框架,但也有难度,一般大公司都有自己的实体框架,有不懂的地方可以和我交流。
Tags:  凡客诚品实体店 实体守护者的忠告 实体店 实体经济 实体框架

延伸阅读

最新评论

发表评论