写一个接口,有增删改查,然后在所有的实体类里分别实现,这样封装接口可以么namespace EntityClass
{
/// <summary>
/// 操作数据库通用接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IEntryOperate<T>
{
/// <summary>
/// 插入指定对象到数据库中
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool InsertEntity(T entity);
/// <summary>
/// 更新对象属性到数据库中
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool UpdateEntity(T entity);
/// <summary>
/// 删除数据库中指定对象
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool DeleteEntity(T entity);
}
}
{
/// <summary>
/// 操作数据库通用接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IEntryOperate<T>
{
/// <summary>
/// 插入指定对象到数据库中
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool InsertEntity(T entity);
/// <summary>
/// 更新对象属性到数据库中
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool UpdateEntity(T entity);
/// <summary>
/// 删除数据库中指定对象
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
bool DeleteEntity(T entity);
}
}
解决方案 »
- 怎么样能多线程,获取一个全局唯一的值。
- c# 窗体中DATAGRIDVIEW控件显示问题
- 问大家一个字符串拆分的问题,高手们没事帮我看看。
- 请问在ASP.NET中,如何能实现winform中ComboBos的功能,即又可以输入,又能下拉,类似与IE浏览器的地址栏?
- 委托到底是声明在命名空间下还是某个类下面?
- 取得2个字符串之间的字符用那个类 ?
- 想用C#做一个网络机房管理软件!想请大家给点思路!
- 初学者的一个问题: 找不到文件或程序集名称“System",或找不到它的一个依赖项。
- 安装treeview时遇到地问题
- 如何编程控制水晶报表中报表页眉的问题?
- 由“期货交易软件”想到的问题 请大家自由讨论
- VC中怎么调用flash
否则 你访问不到接口中的方法!
{ public interface IEntryOperate
{ bool InsertEntity<T>(T entity); bool UpdateEntity<T>(T entity); bool DeleteEntity<T>(T entity);
}
}
此外,返回bool类型结果其实是画蛇添足、从20年前过时的书上学来的设计风格。如果程序异常,会抛出Exception,这就够了。
http://heyant.com/html/Download55.html
namespace EntityClass
{
public interface IEntryOperate
{
void InsertEntity();
void UpdateEntity();
void DeleteEntity();
}
}
查询都是有条件,如何做到通用啊,而且返回类型是什么可能确定么?DataTable?
{
(from u in database.Users where u.Monthly>15000 select u)
.ToList().ForEach(u=>{ database.Users.DeleteOnSubmit(u); });
database.SubmitChanges();
}就这么简单,这才是“通用数据库操作”。哪里用得着八股地一个一个实体类去搞什么“通用数据库操作”?如果八股地为了分层而分层,还不如不要分层,那样还少一些编程设计麻烦。
namespace EntityClass
{
/// <summary>
/// 操作数据库通用接口
/// </summary>
public interface IEntryOperate
{
bool InsertEntity<T>(T entity);
bool UpdateEntity<T>(T entity);
bool DeleteEntity<T>(T entity);
DataTable Query(string sql);
void ExecuteNonQuery(string sql);
}
}
{
bool ExecuteNonQuery(string sql);
DataTable Query(string sql);
bool InsertEntity(IEntity entity);
IEntity GetEntity(IEntity entity);
bool UpdateEntity(IEntity entity);
bool DeleteEntity(IEntity entity);
object ExecuteScalar(string sql);
}
2.实体类接口 public interface IEntity
{
}
3.实体类,实现接口(父类也可以) public class test2 : MohuFramework.Entity.IEntity
{
private int? _id;
public int? id
{
get{ return _id;}
set{ _id = value; }
}
private string _names;
public string names
{
get{ return _names;}
set{ _names = value; }
}
private string _nothing;
public string nothing
{
get{ return _nothing;}
set{ _nothing = value; }
}
}
4.实现数据库操作类 public class SqlDataAccessor : IDataAccessor
{
private static object _lock = new object();//线程锁 //获取sql连接
private SqlConnection GetSqlConnection()
{
string strConn = MohuFramework.Common.ConfigSettings.GetConnectionString();
SqlConnection conn = new SqlConnection(strConn);
return conn;
} public bool InsertEntity(IEntity entity)
{
SqlConnection conn = null;
try
{
Type type = entity.GetType();
PropertyInfo[] list = type.GetProperties();
conn = GetSqlConnection();
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn; //生成sql语句
StringBuilder sql = new StringBuilder();
StringBuilder sqlValue = new StringBuilder();
sql.Append("insert into " + type.Name + "(");
sqlValue.Append(" values(");
string keyName = this.GetKeyName(type.Name);
foreach (PropertyInfo info in list)
{
if (info.Name == keyName ||
info.GetValue(entity, null) == null)
{
continue;
}
sql.Append("[" + info.Name + "],");
sqlValue.Append("@" + info.Name + ",");
SqlParameter p = new SqlParameter();
p.ParameterName = "@" + info.Name;
p.Value = info.GetValue(entity, null);
cmd.Parameters.Add(p);
}
string sqlGetId = "select max(" + keyName + ") from " + type.Name;
string cmdText = sql.ToString().TrimEnd(new char[] { ',' }) + ")" +
sqlValue.ToString().TrimEnd(new char[] { ',' }) + ");" + sqlGetId;
cmd.CommandText = cmdText; //找主键
PropertyInfo pi = null;
foreach (PropertyInfo info in list)
{
if (info.Name == keyName)
{
pi = info;
break;
}
} //执行并给ID赋值
lock (_lock)
{
object id = cmd.ExecuteScalar();
pi.SetValue(entity, id, null);
}
return true;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
if (conn != null)
{
conn.Close();
}
}
} public bool DeleteEntity(IEntity entity)
{
SqlConnection conn = null;
SqlTransaction tran = null;
try
{
Type type = entity.GetType();
PropertyInfo[] list = type.GetProperties();
conn = GetSqlConnection();
conn.Open();
tran = conn.BeginTransaction();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.Transaction = tran; string sql = "delete from " + type.Name + " where ";
string keyName = this.GetKeyName(type.Name);
foreach (PropertyInfo info in list)
{
if (info.Name == keyName)
{
sql += info.Name + "=" + info.GetValue(entity, null);
break;
}
}
cmd.CommandText = sql;
cmd.ExecuteNonQuery();
tran.Commit();
return true;
}
catch (Exception ex)
{
if (tran != null)
{
tran.Rollback();
}
throw new Exception(ex.Message);
}
finally
{
if (conn != null)
{
conn.Close();
}
}
}
}
5.调用 IDataAccessor da = DataAccessorFactory.Instance.GetDataAccessor(DataAccessorFactory.AccessorType.SqlServer);
Test t = new Test();//任何实体都可以
t.name = rnd.Next().ToString() + i.ToString();
da.InsertEntity(t);
using System.Linq;namespace WuweiCommon
{
public interface IDomain : IDisposable
{
IQueryable<T> Cast<T>() where T : class;
void Insert<T>(T obj) where T : class;
void Update<T>(T obj) where T : class;
void Delete<T>(T obj) where T : class;
void Commit();
}
}另一个实现它的抽象类Domain只是增加了“触发器和CacheDependency支持”功能,然后各种数据库的DAL是从这个抽象类继承来的(于是也就具有IDomain接口)。其实这个东西很简单,正因为简单,你就应该从难点入手,而不是纠缠于简单的东西(因为回避难点而好几年都在那里原地踏步)。正如#15楼的简单demo演示的,在BLL代码中调用通用DAL进行编程的需求会很灵活,你可能在开发时随时想更改where之后的条件,甚至多种类型对象进行join操作等等,那种在实体类上面搞个DAL类的做法怎么应付得来对真正的开发效率的需求呢?
意义何在?接口只是定义了一组服务,要实体类继承它是想让实体类实现这组服务,那么这组服务是什么,是CRUD?实体类是CRUD操作的被作用者,而不是执行者。
不正确,假如sql是这样写的:insert into table_name (field_list) values (pk_value,other_value_list) where not exists select pk_value from table_name如果插入重复pk_value,other_value_list(在并发操作时常常会发生),这个sql既不会插入记录也不会抛出异常,但是effectedcount = 0所以你如果想判断增删改操作是否成功,只能判断effectedcount的值。
Exception在这种情况下不适宜。因为:
Exception一般多用于不可意料的例外,增删改操作不成功,无外乎数据是无效的,这种情况完全可以意料到,但你去不能意料到数据库连接是否正常(比如数据库服务器宕机),因此lz不能用exception来敷衍增删改操作,这样会产生不友好的GUI。
{ public interface IEntryOperate<T> where T : new()
{ int Insert(T entity); int Update(T entity); int Delete(T entity);
}
}
这组服务确实是CRUD,自己也没太想明白为什么领导要求这样做。感觉完全颠倒了。