写一个接口,有增删改查,然后在所有的实体类里分别实现,这样封装接口可以么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);
    }
}

解决方案 »

  1.   

    看了代码了  按楼主的想法来说是可以实现的! 但是在你要调用接口中的方法的时候 一定好注意 创建的对象应该是接口对象 例如  : 接口名 句柄名 = new 接口实现类();
    否则 你访问不到接口中的方法!
      

  2.   

    既然是操作数据库的“通用接口”,那么class就跟具体类型没有关系,而只有方法才跟数据类型有关,例如:namespace EntityClass
    {    public interface IEntryOperate
        {        bool InsertEntity<T>(T entity);        bool UpdateEntity<T>(T entity);        bool DeleteEntity<T>(T entity);
        }
    }
    此外,返回bool类型结果其实是画蛇添足、从20年前过时的书上学来的设计风格。如果程序异常,会抛出Exception,这就够了。
      

  3.   

    朋友,我也正在尝试这样做,下载我这个看看吧
    http://heyant.com/html/Download55.html
      

  4.   

    放在实体类中实现?那么这岂不是“竖井式思维”。那种所谓一句每一个实体类来实现DAL的做法不要也罢,实在是太滥太枯燥太臃肿太八股了吧。正如我所改的接口所示,如果你要写一个通用数据库类,它就是一个数据库接口,它处理各种业务实体,而它自己不是业务实体。
      

  5.   

    既然是实体类的接口,就不用传个类型进来吧
    namespace EntityClass
    {
        public interface IEntryOperate
        {
            void InsertEntity();
            void UpdateEntity();
            void DeleteEntity();
        }
    }
      

  6.   


    查询都是有条件,如何做到通用啊,而且返回类型是什么可能确定么?DataTable?
      

  7.   

    例如在Linq to SQL 中要删除一组用户资料只要写:using(var database=CreateMyDataContext())
    {
        (from u in database.Users where u.Monthly>15000 select u)
            .ToList().ForEach(u=>{ database.Users.DeleteOnSubmit(u); });
        database.SubmitChanges(); 
    }就这么简单,这才是“通用数据库操作”。哪里用得着八股地一个一个实体类去搞什么“通用数据库操作”?如果八股地为了分层而分层,还不如不要分层,那样还少一些编程设计麻烦。
      

  8.   


    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);
        }
    }
      

  9.   

    在我#15楼引用的那两句Linq to SQL的程序中,“打开数据库连接、通用查询、简单操作、事务提交”全都包括了,而且你随时想起了什么功能就可以立刻写出来,就像写SQL语句一样方便,而它又是强类型的。你可以通过了解各种架构,扩展部分底层的核心功能,但是没有必要白手起家自己从头在那里做底层开发啊。
      

  10.   

    1.定义数据库操作类的接口,注意是操作类,不是实体类    public interface IDataAccessor
        {
            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);
      

  11.   

    还是根据我#15楼所写的那两句Linq to SQL代码(我其实从来不使用Linq to SQL,只是知道它而已),我看到网上的一些“范例”,竟然要写什么User类的DAL类,把那句代码再嵌入什么User.Delete(Monthly)方法中,你是是不是脱裤子放屁啊?!Linq to SQL本身就是高级别的DAL通用框架,直接在BLL中调用它来处理数据库中的User对象就可以了,还要自己在User类上写什么DAL么?
      

  12.   

    你是是不是脱裤子放屁啊   -->  通过比对这个例子,你说是那种再写实体的DAL类的方法是不是脱裤子放屁啊
      

  13.   

    DAL只有这一点的东西,例如我的DAL接口:using System;
    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类的做法怎么应付得来对真正的开发效率的需求呢?
      

  14.   

    有无数的帖子骂过所谓DAL层开发在项目中带来的无尽的麻烦,我来给你说清楚为什么产生麻烦,如何越过泥潭。
      

  15.   


    意义何在?接口只是定义了一组服务,要实体类继承它是想让实体类实现这组服务,那么这组服务是什么,是CRUD?实体类是CRUD操作的被作用者,而不是执行者。
      

  16.   


    不正确,假如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的值。
      

  17.   

    因此lz应该将bool改为unsigned integer
      

  18.   


    Exception在这种情况下不适宜。因为:
    Exception一般多用于不可意料的例外,增删改操作不成功,无外乎数据是无效的,这种情况完全可以意料到,但你去不能意料到数据库连接是否正常(比如数据库服务器宕机),因此lz不能用exception来敷衍增删改操作,这样会产生不友好的GUI。
      

  19.   

    给你一个简洁的写法作为参考namespace EntityClass
    {    public interface IEntryOperate<T> where T : new()
        {        int Insert(T entity);        int Update(T entity);        int Delete(T entity);
        }
    }
      

  20.   


    这组服务确实是CRUD,自己也没太想明白为什么领导要求这样做。感觉完全颠倒了。