支持差异数据保存的数据库实体类设计(一)
面向对象开发过程中大家经常碰到的一个东东——数据实体。
在实体对象实例的某一个信息被修改后,面临一个数据保存的问题,网上可以搜索到很多不同的保存方法,这里提供小虾(本人)曾经用过的几种常用方法:
根据需要,将修改过的属性组合成SQL语句(未修改的属性不作处理),然后执行数据库命令保存数据;
提前写好实体对象的SQL语句,如string sql = "UPDATE
TableName SET ColumnName1 = {0}, ColumnName2 = {1},
... WHERE PK_ColumnName = {N}",然后将整个实体对象作为参数传入,将保存实体对象的SQL语句中的参数替换成相应的值,得到保存数据的SQL语句,然后调用数据库命令保存数据;
将实体对象实例中的每一个数据库字段属性成员的“属性名”和“属性值”通过反射的方法读取出来,然后拼接字符串,然后调用数据库命令来保存数据;
...(或许还有很多更加高效的数据库实体类,希望大家踊跃拍砖)。
在这里,小虾分别说说每一种方法的优缺点。
|
优点 |
缺点 |
第一种 |
1.支持差异数据保存,即只保存修改过的数据库字段;
2.由于是已经是编辑好的SQL语句,所以性能还可以。
|
1.需要写非常多的SQL语句。 |
第二种 |
1.不支持差异数据保存;
2.执行效率也还可以。
|
1.一个实体对象至少需要一个SQL语句,工作量也是很客观的。 |
第三种 |
1.不支持差异数据保存。
2.由于是通过反射方式来拼接SQL语句,所以省掉了很多写sql语句的工作量。
|
1.同样是由于反射操作,带来的性能影响也是比较大的。 |
如上三种方法都很难达到各位的需求,不知道是否更好的数据库实体设计方法,还是那句话,欢迎大家大胆拍砖!
@追加内容
哎,一个个只是支持,顶下什么的,悲惨啊!
看来还得去baidu,google了。
支持差异数据保存的数据库实体类设计(二)
首先声明一下,小虾的写文章的水平那是相当的两字——很菜!所以碰到看不明白的文字,请大家留言,我会作特别回答。
下面直接入正题。
自定义数据库实体类测试版已经出炉(编程语言为C#),支持差异数据保存,0反射,几乎是0查询语句,效率在一定程度上也是很客观的,但是还没有跟原始的DataTable数据绑定进行对比,这个工作留着下一步完成,先说本文重点。
1、支持差异数据保存
如果想做到这一点, 大家最容易想到的就是添加一个标记,用于记录当前属性的值是否被修改过。
先上一段传统的数据库实体类的设计方法:
public class Entity
{
public int IntValue{get; set ;}
public int StringValue{get; set ;}
public int BoolValue{get; set ;}
public int DoubleValue{get; set ;}
public int DateTimeValue{get; set ;}
}
如果简单的通过在实体类中添加一个标记来记录每个属性是否被修改过,当然是不可行的,因为你根本就不知道每个实体有多少个属性,而且你还必须在每个标记和属性之间建立联系.这个时候,一个数据类型对象浮现在脑海中,就是放弃传统的int,
bool, string, double, DateTime这些数据类型,当然也不是完全放弃,只是对这些简单类型进行一次封装,这样字一个初步的数据类型对象就产生了:
1 public class MInt
2 {
3 public int Value{get; set; }
4 public bool ValueChanged{get; set; }
5 }
这样传统的数据库实体类就要做适当的调整了:
1 public class NewEntity
2 {
3 public MInt IntValue{get;set;}
4 public MString StringValue{get;set;}
5 public MBool BoolValue{get;set;}
6 public MDouble DoubleValue{get;set;}
7 public MDateTime DateTimeValue{get;set;}
8 }
为了能够更好的支持DBNull类型的数据保存到数据库,需要在数据类型对象添加一个标记IsNull,这样在进行数据保存只要判断对象是否为空,如果为空,则在更新,或者插入数据的时候,直接赋值DBNull.Value即可,这里只是对数据类型对象其中的一小块扩展,下面还会有很多其他的,请继续往下走。
2、0查询语句
说到0查询语句,小虾在这里说了句大话了,不管怎样,先看看小虾是如何实现的吧。
小虾的查询语句包括4种类型:Select, Delete, Update,
Insert;做过开发的人都知道,每次新增加一个实体对象,都需要写一大堆的查询语句,简直是揪心。不过等你看了这篇文章以后,相信你从此就不用再揪心了。
文章开头提到了0反射,但是不通过反射又如何获取实体对象中的每一个属性的名称和值呢?大家很容易想到的就是枚举了,对,我也是这么想的,通过集合的方式,将实体对象中的所有属性都装到集合中,小虾准备用IList<T>。但是新的问题又出现了我们的实体对象的属性的类型是MInt,
MBool, MString。。。如何让他能够支持IList<T>呢。所有需要对原始的数据类型对象进行一下修改了,让他们全部继承自一个对象TypeBase不就行了吗?这样一个数据类型对象基类就产生了:
1 public abstract
class TypeBase
2 {
3 /// <summary>
4 /// 值
5 /// </summary>
6 public abstract object ObjectValue { get; set; }
7
8 /// <summary>
9 /// 是否为空
10 /// </summary>
11 public abstract bool IsNull { get; set; }
12
13 /// <summary>
14 /// 值是否改变
15 /// </summary>
16 public abstract bool ValueChanged { get; set; }
17 }
按照上文将的,为了能够达到遍历实体对象内部的每一个属性,而且达到0查询语句的效果,我们的自定义数据库实体类就应该再一次进行修改了:
View Code
public class NewEntity
{
#region 静态对象, 数据库表名,字段名
//表名
public static string TABLENAME = "NEWENTITY";
//数据库字段名
public static string INTVALUE= "IntValue";
public static string STRINGVALUE= "StringValue";
public static string BOOLVALUE= "BoolValue";
public static string DOUBLEVALUE= "DoubleValue";
public static string DATETIMEVALUE= "DateTimeValue";
#endregion #region
属性成员 //属性结合,用于存放该实体对象的所有属性,以便于之后的遍历
public IList<TypeBase> ListField{get; private
set;}
//数据表名,一边能够通过实例成员获取到该实体对象所对应的数据库表名
public string TableName {get{ return TABLENAME; }}
//实体属性
public MInt IntValue{get;set;}
public MString StringVa;}
public MBool BoolValue{get;set;}
public MDouble DoubleValue{get;set;}
public MDateTime DateTime;}
#endregion #region
构造函数 //无参数构造
//在构造对象的时候,小虾将每个字段的数据库字段的字段名引用传输属性中保存,也是为了方便只有在遍历
//属性集合的时候,能够获取该属性的值,同时能够获取到该属性对于的数据库字段名
//用ref传参,是尽量保证一个数据库字段名,在内存中只有一个引用,在一定程度上减少了内存开销
public NewEntity()
{
this.IntValue = new IntValue(ref INTVALUE);
this.StringValue= new StringValue(ref STRINGVALUE);
this.BoolValue= new IntValue(ref BOOLVALUE);
this.DoubleValue= new DoubleValue(ref DOUBLEVALUE);
this.DateTimeValue= new DateTimeValue(ref DATETIMEVALUE);
///将所有属性添加到属性集合中
this._AddFieldToList();
}
//DataRow对象构造
public NewEntity(DataRow row)
{
this.IntValue = Convert.ToMyInt(row[INTVALUE], ref INTVALUE);
this.StringValue= Convert.ToMyString(row[STRINGVALUE],
ref STRINGVALUE);
this.BoolValue= Convert.ToMyBool(row[BOOLVALUE], ref
BOOLVALUE);
this.DoubleValue= Convert.ToMyDouble(row[DOUBLEVALUE],
ref DOUBLEVALUE);
this.DateTimeValue= Convert.ToMyDateTime(row[DATETIMEVALUE],
ref DATETIMEVALUE);
///将所有属性添加到属性集合中
this._AddFieldToList();
} #endregion
#region 私有方法
///将所有属性添加到属性集合中
private void _AddFieldToList()
{
if(this.ListField == null) this.ListField = new List<TypeBase>();
this.ListField.Add(this.IntValue);
this.ListField.Add(this.StringValue);
this.ListField.Add(this.BoolValue);
this.ListField.Add(this.DoubleValue);
this.ListField.Add(this.DateTimeValue);
}
#endregion
}
展开代码,一看这么多行,可别直接一拖到底,仔细的研究一下,有了这样一个实体类才能够满足我们的0查询语句。
有一点要提出来的就是,我在每个实体属性对象中加了两个字段:ColumnName,该字段通过构造函数中给每个属性赋值的时候传入,
在这里还是贴一下代码,方便下文调用,同时也给大家少一些疑惑:
public abstract
class TypeBase
{
/// <summary>
/// 值
/// </summary>
public abstract object ObjectValue { get; set; }
/// <summary>
/// 是否为空
/// </summary>
public abstract bool IsNull { get; set; }
/// <summary>
/// 值是否改变
/// </summary>
public abstract bool ValueChanged { get; set; }
/// <summary>
/// 该属性对应数据库字段的字段名
/// </summary>
public abstract string ColumnName{ get; set; }
}
至于里面其他代码的用意,在这里就不多讲了,看注释基本上就能够懂了,还有问题的,请留言,我会做特别回复。
3、如何实现0查询语句
能看到这里的人,说明你真正关注的是,如何做到0查询语句,下面小虾就来讲讲如何实现0查询语句。
在将如何实现0查询语句之前,我这里有一个特别的说明,就是在每个数据库实体对象中,你必须保证有一个主键字段:MyInt
ID,这样我们在update和delete的时候就可以通过这个唯一字段来处理。
直接上代码:
//保存对象
public bool Save()
{
if(this.Id.Value = 0) this.Insert();
else this.Update();
} //插入对象
public bool Insert()
{
//这里通过一个公共方法,获取该对象的下一个Id
int Id = Utils.GetNextId(this.TableName);
string sql1 = "INSERT INTO " + tb.TableName
+ "(Id";
string sql2 = "(" + Id.ToString() + ",";
foreach(TypeBase tb in this.ListField)
{
sql1 += "," + tb.ColumnName;
//这里说明一下tb.ToString()方法需要在每一个种类型中进行重写
//如MyInt类型的对象的ToString()的返回值直接是ObjectValue.ToString();
//如MyString类型的对象的ToString()的返回值直接是"'" + ObjectValue.ToString()
+ "'";
//等等,其他的就不多说了。
sql2 += "," +tb.ToString();
}
sql1 +=") VALUES" + sql2 + ")";
//然后再执行数据库命令
return DbHelper.ExecCommand(sql);
} //更新对象
public bool Update()
{
//更新对象的具体实现就不多啰嗦了,相信大家都会了,但是有一点需要提出的是,在update的时候,需要判断TypeBase.ValueChanged==true的时候,才做数据更行,否则不做处理,这样才能够达到文章题目的差异数据保存
} //删除对象
public bool Delete()
{
//very easy.
//DELETE FROM TableName WHERE ID = ID....
}
看完代码,大家可能会有很多疑问,莫非每个对象都要写这么几个Save(),
Insert(), Update(), Delete()方法,那岂不是比写sql语句还要累,或许你现在还会这么讲,但是相信凭你神一般的抽象能力,我想在一又三分子一秒之后,你肯定一拍脑袋,把数据库实体类抽象出来,然后把这几个方法放在基类中不久一切ok了吗,如果能想到这里,小虾只能说:哎,知音啊!
讲到这里,小虾的0查询语句就基本上是讲完了,或许你会说还有个查询语句没讲呢,小虾想说的是,查询功能就像打太极,几乎是千变万化,
无所不有,无坚不摧, 无...这些我就留到小虾接下来的文章中讲解。
接下来的文章可能包括:
1.自定义数据库实体类之基类抽象——ObjBase对象搭建
可能提供方法有:Save();Delete();DeleteById();GetListObject<T>(param1...);
2、自定义数据库实体类之查询语句对象——QueryString对象的实现
QueryString对象:类似Linq的数据库查询语句的写法,但是写法又更简单,更舒服,更。。。。请大家期待。
可能出现的语法有:QueryString.Select(...).From(...).Where(new
Condition().And().Or()..).And().OrderBy();
支持差异数据保存的数据库实体类设计(三)(——基类抽象ObjBase的构建以及子类实现
一直处于纠结的边缘,左右不是,不知何去何从,想写点东西,有不知道写点什么,总是手高眼底,想一大通,做的极少,最终总是浑浑噩噩的锅,什么也没完成。今天受到路过秋天大哥的鼓励,才让我继续我之前未完成的文章些列,在这里先谢过。
在这篇文章主要讲述数据库实体基类对象ObjBase的构建,首先来一张图片,该图片展示了这套数据库实体所需要的所有类结构:
FieldType目录:用于存放所有数据库实体属性类型对象(其中FieldTypeBase为实体属性类型基类),里面的具体细节在本系列的第一篇和第二篇文章中都已经讲述过,在这里就不多讲了;
DalAgent.cs:该类是一个静态类,主要包含一些对象的数据库操作的公共方法;
ObjBase.cs:该类只有1个Id属性,也就是我们这篇文章的主角了,稍后详细讲解;
ObjFactoryBase:对象数据库操作类基类;
ObjNamedBase.cs:该类继承自ObjBase,主要有3个属性:Name,Description,SortOrder,作为所有包含Name/Description信息的对象的基类,SortOrder属性的存在主要是为了排序功能。
ObjTypeBase.cs:该类继承自ObjNamedBase,有2个属性:ObjTypeId,DataGroupId,作为所有包含“类别”信息的对象的基类,DataGroupId用于存放数据组编号,用于对象授权访问功能。
下面进入本文主角:ObjBase类:
View Code
namespace SAS.ORM
{
using System;
using System.Collections.Generic;
using System.Data;
using SAS.ORM.FieldType;
/// <summary>
/// NameSpace :: SAS.ORM
/// Creater :: ZhouWei
/// Create Time :: 2011-5-18 0:52:13
/// </summary>
public abstract class ObjBase
{
/// <summary>
/// 对象所有属性集合
/// </summary>
internal Dictionary<string, FieldTypeBase> DicField;
#region 数据库字段名
/// <summary>
/// 数据库列名
/// </summary>
public static string ID = "ID";
#endregion
#region 公共字段/属性
/// <summary>
/// 编号
/// </summary>
public MInt Id { get; set; }
#endregion
#region 构造函数
public ObjBase() { }
public ObjBase(DataRow row)
{
//初始化对象
this.FillObject(row);
}
#endregion
#region 继承可见方法
/// <summary>
/// 将字段添加到列表集合中
/// </summary>
/// <param name="field"></param>
protected void AddField(FieldTypeBase field)
{
this.DicField.Add(field.ColumnName, field);
}
/// <summary>
/// 获取DataRow指定列的值,如果找不到指定列,则返回DBNull.Value
/// 以满足当只查询对象的某些列的时候。
/// </summary>
/// <param name="row"></param>
/// <param name="fieldName"></param>
/// <returns></returns>
protected object GetFieldValue(DataRow row, ref string
fieldName)
{
if (!row.Table.Columns.Contains(fieldName)) return
null;
return row[fieldName];
}
#endregion
#region 公共方法/属性
/// <summary>
/// 通过DataRow进行对象初始化
/// </summary>
/// <param name="row">DataRow</param>
public virtual void FillObject(DataRow row)
{
//初始化属性集合
DicField = new Dictionary<string, FieldTypeBase>();
//初始化属性值
if (row == null)
{
this.Id = new MInt(ref ID, 0);
}
else
{
this.Id = new MInt(ref ID, this.GetFieldValue(row,
ref ID));
}
//添加属性到集合
this.AddField(this.Id);
}
/// <summary>
/// 通过DataRow进行对象初始化, 用于关联对象的填充
/// </summary>
/// <param name="row">DataRow</param>
public virtual void FillRelationObject(DataRow row)
{
this.FillObject(row);
}
/// <summary>
/// 根据列名获取属性值
/// </summary>
/// <param name="filedName">字段名</param>
/// <returns></returns>
public object GetField(string filedName)
{
if (DicField == null) return string.Empty;
if (DicField.ContainsKey(filedName)) return this.DicField[filedName];
return string.Empty;
}
/// <summary>
/// 保存this
/// </summary>
/// <returns></returns>
public virtual bool Save()
{
return DalAgent.Save(this);
}
/// <summary>
/// 删除this
/// </summary>
/// <returns></returns>
public virtual bool Delete()
{
return DalAgent.Delete(this);
}
/// <summary>
/// 数据库表名
/// </summary>
public abstract string TableName { get; }
#endregion
}
}
该ObjBase基类主要包括以下内容
1、一个包内字段DicField,用于装载实体对象的所有属性(主要用于保存或者更新对象时的遍历操作)
2、1个静态字段,ID;
3、1个属性(数据库字段)Id,也就说,应用该ORM的所有数据库实体对象都必须有一个字段“Id";
4、2个构造函数,一个是空构造(空构造的时候,实体类内部所有属性-数据库字段的值都为null,在该基类中就一个Id属性),一个是DataRow对象构造(将DataRow对象中的Id列的值填充到实体类的Id属性中);
5、继承可见方法:protected void AddField(FieldTypeBase
field);该方法有一个FieldTypeBase参数,功能是将该属性添加到DicField中;
protected object GetFieldValue(DataRow
row, ref string fieldName);该方法有两个参数,功能是将在DataRow对象找指定列名的单元格的值;
6、公共方法/属性:public virtual void FillObject(DataRow
row);//填充对象
public virtual void FillRelationObject(DataRow
row);//填充对象,主要用于有关联表查询的时候的填充,具体实现在子类中重写
public object GetField(string filedName);//根据数据库列名,获取该列的值,也是在关联表查询中用到的,因为在一般实体表查询的时候,通过属性名即可获取属性值。
public virtual bool Save();//保存对象
public virtual bool Delete();//删除对象
public abstract string TableName {
get; }//这个字段的存在主要便于如下调用,obj.TableName。在子类中还会有一个静态字段TABLENAME,主要便于如下调用ObjClass.TABLENAME;
下面来看看我的业务层调用:
首先介绍下下面实例中所需要用到的两个表(Note/随笔表,NoteTag/随笔标签表)的字段以及实体类的代码:
随笔表结构/实体类代码
namespace Blog.BLL.Data
{
using System.Data;
using SAS.ORM;
using SAS.ORM.FieldType;
/// <summary>
/// MNote对象实体类
/// </summary>
public class Note : ObjBase
{
#region 表名、字段名
public static string TABLENAME =
"MNOTE";
public static string AGAINST = "AGAINST";
public static string BODY = "BODY";
public static string CREATEBY = "CREATEBY";
public static string CREATETIME = "CREATETIME";
public static string HITCOUNT = "HITCOUNT";
public static string LASTMODTIME = "LASTMODTIME";
public static string LASTREPLYBY = "LASTREPLYBY";
public static string LASTREPLYTIME = "LASTREPLYTIME";
public static string REPLYCOUNT = "REPLYCOUNT";
public static string SITETYPEID = "SITETYPEID";
public static string SUPPORT = "SUPPORT";
public static string TAGID = "TAGID";
public static string TITLE = "TITLE";
public static string TAGNAME = "TAGNAME";
#endregion
#region 公共属性
public override string TableName
{ get { return TABLENAME; } }
public MInt Against { get; set; }
public MString Body { get; set; }
public MInt CreateBy { get; set; }
public MDateTime CreateTime { get; set; }
public MInt HitCount { get; set; }
public MDateTime LastModTime { get; set; }
public MInt LastReplyBy { get; set; }
public MInt LastReplyTime { get; set; }
public MInt ReplyCount { get; set; }
public MInt SiteTypeId { get; set; }
public MInt Support { get; set; }
public MInt TagId { get; set; }
public MString Title { get; set; }
#endregion
#region 构造函数
public Note() { }
public Note(DataRow row)
{
this.FillObject(row);
}
#endregion
#region 其他方法
/// <summary>
/// 通过DataRow进行对象初始化
/// </summary>
/// <param name="row">row</param>
public override void FillObject(DataRow row)
{
base.FillObject(row);
//初始化属性值
if (row == null)
{
this.Against = new MInt(ref AGAINST);
this.Body = new MString(ref BODY);
this.CreateBy = new MInt(ref CREATEBY);
this.CreateTime = new MDateTime(ref CREATETIME);
this.HitCount = new MInt(ref HITCOUNT);
this.LastModTime = new MDateTime(ref LASTMODTIME);
this.LastReplyBy = new MInt(ref LASTREPLYBY);
this.LastReplyTime = new MInt(ref LASTREPLYTIME);
this.ReplyCount = new MInt(ref REPLYCOUNT);
this.SiteTypeId = new MInt(ref SITETYPEID);
this.Support = new MInt(ref SUPPORT);
this.TagId = new MInt(ref TAGID);
this.Title = new MString(ref TITLE);
}
else
{
this.Against = new MInt(ref AGAINST, this.GetFieldValue(row,
ref AGAINST));
this.Body = new MString(ref BODY, this.GetFieldValue(row,
ref BODY));
this.CreateBy = new MInt(ref CREATEBY, this.GetFieldValue(row,
ref CREATEBY));
this.CreateTime = new MDateTime(ref CREATETIME, this.GetFieldValue(row,
ref CREATETIME));
this.HitCount = new MInt(ref HITCOUNT, this.GetFieldValue(row,
ref HITCOUNT));
this.LastModTime = new MDateTime(ref LASTMODTIME,
this.GetFieldValue(row, ref LASTMODTIME));
this.LastReplyBy = new MInt(ref LASTREPLYBY, this.GetFieldValue(row,
ref LASTREPLYBY));
this.LastReplyTime = new MInt(ref LASTREPLYTIME, this.GetFieldValue(row,
ref LASTREPLYTIME));
this.ReplyCount = new MInt(ref REPLYCOUNT, this.GetFieldValue(row,
ref REPLYCOUNT));
this.SiteTypeId = new MInt(ref SITETYPEID, this.GetFieldValue(row,
ref SITETYPEID));
this.Support = new MInt(ref SUPPORT, this.GetFieldValue(row,
ref SUPPORT));
this.TagId = new MInt(ref TAGID, this.GetFieldValue(row,
ref TAGID));
this.Title = new MString(ref TITLE, this.GetFieldValue(row,
ref TITLE));
}
//添加属性到集合
this.AddField(this.Against);
this.AddField(this.Body);
this.AddField(this.CreateBy);
this.AddField(this.CreateTime);
this.AddField(this.HitCount);
this.AddField(this.LastModTime);
this.AddField(this.LastReplyBy);
this.AddField(this.LastReplyTime);
this.AddField(this.ReplyCount);
this.AddField(this.SiteTypeId);
this.AddField(this.Support);
this.AddField(this.TagId);
this.AddField(this.Title);
}
/// <summary>
/// 通过DataRow进行对象初始化, 用于关联对象的填充
/// </summary>
/// <param name="row">DataRow</param>
public override void FillRelationObject(DataRow row)
{
this.FillObject(row);
MString obj;
object o = this.GetFieldValue(row, ref TAGNAME);
if (o != null)
{
obj = new MString(ref TAGNAME, o);
obj.NeedSave = false;
this.AddField(obj);
}
}
#endregion
}
}
随笔标签表结构/实体类代码
namespace Blog.BLL.Data
{
using System.Data;
using SAS.ORM;
using SAS.ORM.FieldType;
/// <summary>
/// NoteTag对象实体类
/// </summary>
public class NoteTag : ObjNamedBase
{
#region 表名、字段名
public static string TABLENAME =
"NOTETAG";
#endregion
#region 公共属性
public override string TableName
{ get { return TABLENAME; } }
#endregion
#region 构造函数
public NoteTag() { }
public NoteTag(DataRow row)
{
this.FillObject(row);
}
/// <summary>
/// 通过DataRow进行对象初始化, 用于关联对象的填充
/// </summary>
/// <param name="row">DataRow</param>
public override void FillObject(DataRow row)
{
base.FillObject(row);
}
#endregion
}
}
1、获取数据列表对象:
static string _SQL_GetNoteList = "SELECT
n.*, nt.Name as TagName from [Note] n, NoteTag nt where
n.TagId = nt.Id";
//获取关联信息对象列表
IList<Note> list = DalAgent.GetListRelationObject<Note>(_SQL_GetNoteList,
null);
//获取自身信息对象列表
IList<Note> list = DalAgent.GetListObject<Note>("select
* from [Note] where Id < 100", null);
//获取自身信息全部对象列表
IList<Note> list = DalAgent.GetListAll<Note>(Note.TABLENAME);
2、实体对象属性值获取
Note n = list[0]; (该list由DalAgent.GetListRelationObject<Note>(_SQL_GetNoteList,
ref pi, orderBy, null)方法获取
1)、自身属性值获取:n.Title, n.Body...
2)、关联表属性值获取:n.GetField(Note.TAGNAME).ToString();其中“Note.TAGNAME”为关联表字段,从查询语句中可以看到。
3、实体对象的插入
Note note = new Note();//构造一个空对象
note.Fill(null);//利用一个空DataRow对象来填充note,如果不进行这一步,note的所有属性都为null,导致在调用note.Id的时候会直接报错。
note.Id.SetValue(0);//然后给Id赋值
note.Title.SetValue(title + i.ToString());//给Title赋值
note.TagId.SetValue(tagId);//给TagId赋值
note.CreateTime.SetValue(DateTime.Now);//给CreateTime赋值
note.Save();//插入
4、实体对象的保存
Note note = DalAgent.GetObjectById<Note>(Note.TableName,
1);//获取Id为1的Note对象
note.CreateTime.SetValue(DateTime.Now);//给CreateTime重新赋值
note.Save();//更新数据库
5、实体对象的删除
Note note = DalAgent.GetObjectById<Note>(Note.TableName,
1);//获取Id为1的Note对象
note.Delete();//删除对象
|