/// <summary>
/// DataElement
/// 数据对象类型的基础类 实现各个表通用操作方法
/// </summary>
public abstract class DataElement
{
/// <summary>
/// 表名
/// </summary>
protected string _TableName;
/// <summary>
/// 主键值
/// </summary>
protected object _PrimaryKeyValue;
public object PrimaryKeyValue
{
get { return _PrimaryKeyValue; }
} /// <summary>
/// 主键列名
/// </summary>
protected string _PrimaryKey; /// <summary>
/// 数据库连接
/// </summary>
protected System.Data.SqlClient.SqlConnection conn; /// <summary>
/// 插入数据的sql字串 根据各个public并且可写的属性 使用反射来构造语句
/// </summary>
protected virtual string _InsertString
{
get
{
System.Reflection.PropertyInfo[] pis = this.GetType().GetProperties();
string[] cols = new string[pis.Length];
string[] vals = new string[pis.Length];
int c = 0;
foreach (System.Reflection.PropertyInfo pi in pis)
{
if (pi.CanWrite)
{
cols[c] = String.Format("[{0}]", pi.Name);
vals[c] = String.Format("'{0}'", pi.GetValue(this, null));
c++;
}
}
return String.Format("INSERT INTO [{0}]({1})VALUES({2})"
, _TableName
, String.Join(",", cols, 0, c)
, String.Join(",", vals, 0, c)
);
}
} /// <summary>
/// 更新数据的sql字符串
/// </summary>
protected virtual string _UpdateString
{
get
{
System.Reflection.PropertyInfo[] pis = this.GetType().GetProperties();
string[] cols = new string[pis.Length];
int c = 0;
foreach (System.Reflection.PropertyInfo pi in pis)
{
if (pi.CanWrite)
{
cols[c++] = String.Format("[{0}]='{1}'", pi.Name, pi.GetValue(this, null));
}
}
return String.Format("UPDATE [{0}] SET {1} WHERE [{2}]='{3}'"
, _TableName
, String.Join(",", cols, 0, c)
, _PrimaryKey
, _PrimaryKeyValue
);
}
} /// <summary>
/// 删除数据的字符串
/// </summary>
protected virtual string _DeleteString
{
get
{
return String.Format("DELETE FROM [{0}] WHERE [{1}]='{2}'", _TableName, _PrimaryKey, _PrimaryKeyValue);
}
} /// <summary>
/// 删除数据的方法
/// </summary>
public void Delete()
{
if (_PrimaryKeyValue == null) throw new Exception("未对主键赋值");
DATAOP.Command(_DeleteString, conn);
} /// <summary>
/// 保存数据的方法 根据主键值是否为空来判断应insert还是update
/// </summary>
public virtual void Save()
{
if (_PrimaryKeyValue == null)
DATAOP.Command(_InsertString, conn);
else
DATAOP.Command(_UpdateString, conn);
} /// <summary>
/// 调用数据的方法
/// </summary>
public virtual void Load()
{
if (_PrimaryKeyValue != null)
{
DataTable dt = DATAOP.DT(
String.Format("SELECT * FROM [{0}] WHERE [{1}]='{2}'", _TableName, _PrimaryKey, _PrimaryKeyValue)
, conn
);
if (dt.Rows.Count > 0)
{
Load(dt.Rows[0]);
}
}
} /// <summary>
/// 根据数据行调用数据 调用多行时可用 不必多次开闭数据库连接
/// </summary>
/// <param name="row"></param>
public void Load(DataRow row)
{
foreach (System.Reflection.PropertyInfo pi in this.GetType().GetProperties())
{
if (pi.CanWrite)
{
if (row.Table.Columns[pi.Name] != null)
{
if (pi.PropertyType.ToString() == "System.Xml.XmlDocument")
{
System.Xml.XmlDocument xd = new System.Xml.XmlDocument();
xd.Load(row[pi.Name].ToString());
pi.SetValue(this, xd, null);
}
else
{
pi.SetValue(this, Convert.ChangeType(row[pi.Name], pi.PropertyType), null);
}
}
}
}
_PrimaryKeyValue = row[_PrimaryKey];
}
/// <summary>
/// 设置主键值
/// </summary>
/// <param name="value"></param>
public void SetPrimaryKeyValue(object value) { _PrimaryKeyValue = value; } /// <summary>
/// 过滤非法字
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
protected virtual string StringFilter(string str) { return str == null ? null : str.Replace("'", "`"); } /// <summary>
/// 过滤非法字并限制字长
/// </summary>
/// <param name="str"></param>
/// <param name="len"></param>
/// <returns></returns>
protected virtual string StringFilter(string str, int len)
{
if (str == null) return null;
str = str.Replace("'", "`");
if (str.Length > len) str = str.Substring(0, len);
return str;
} /// <summary>
/// 反向还原字串
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
protected string StringUnFilter(string str) { return str == null ? null : str.Replace("`", "'"); }
}
主要的心得是insert和update字串通过反射的方式来生成。当然前提是单一的主键。一些简单的数据库操作应该是可以方便得多了。比如一个继承了该类的User类,添加用户的方式如下 void Button1_Click(object sender, EventArgs e)
{
MKCMS.User u = new MKCMS.User();
u.Name = TextBox1.Text.Trim();
u.Password = TextBox2.Text.Trim();
u.Email = TextBox3.Text.Trim();
u.Description = TextBox4.Text.Trim();
u.Save();
}
这样节省了大量的页面代码。希望代码对你有帮助,分数这方面实在囊中羞涩了。
解决方案 »
- 急!!!!!如何让未绑定数据的DataGrid显示用来编辑的空白行?
- 谁能给我一个树形菜单原码,access数据库
- 请问下C#中怎么实现文件的扫描
- Asp.net与Access的DataReader分页(cool!最新献上~)
- 怎样才能在点击table的某一单元格使其显示TextBox,可以输入数据
- 急求从unix系统的ftp服务器上下载文件的代码?
- 大家都知道配货站的物流网程序吧,比如说全国物流信息网一点通,现有人要开发,感兴趣的留下QQ号一块搞搞,望高手指点架构!
- 求教如何在.NET中将EXCEL文件另存为HTML啊
- 100分求解winform邮件发送问题,在线等。..
- C#double类型数据自动转化为科学计数法
- aspx如何获取来源页面的aspx对应的cs对象
- C#中Excel导入到sql sever2000中出问题了
/// 重写保存方法 内置了数据库连接
/// </summary>
public override void Save()
{
if (!CheckName) throw new Exception("已存在此用户名");
else
{
MSSQL sql = new MSSQL();
sql.Open();
conn = sql.Connection;
base.Save();
sql.Close();
sql.Dispose();
}
}这个MSSQL是我上一贴中的数据库连接类,就不再详细叙述了。