在分层的设计中查询出的数据结果一般 用实体集承载、显示数据如
         //获取留言信息--返回List<ContentModule>类型
        public List<Word> ShowWord()
        {
            List<Word> lcontent = new List<Word>();
            string conn = SqlHelper.ConnectionStringLocalTransaction;
            using (SqlDataReader mydr = SqlHelper.ExecuteReader(conn, CommandType.Text, SQLSELECT, null))
            {
                while (mydr.Read())
                {
                    lcontent.Add(Turn (mydr));
                }
            }
            return lcontent;
        }
这种方法对于单表的操作还行(一个实体类对应一个表),
但如果是多表的查询结果就要新建一个对应的实体类来承载查询的结果(因为原来的表的实体类不包含其它表的字段)。--PetShop4中是这样做的。
现在我遇到的问题是我操作的字段比较多,新建一个对应多表的实体类不太合算,所以我就用返回 DataSet的方法,如下
   public DataSet UserList()
        {
            const string mycmd = "多表查询操作"
            DataSet myds = MySQL.ExecuteDataSet(CommandType.Text, mycmd, null);
            return myds;
        }
这样问题是解决了,但用DataSet感觉性能上有所降低,在BLL层还要引入System .Data空间。所以问问大家有没有更好的方法?

解决方案 »

  1.   

    我的3层就是互相得到返回值大多数返回的是bool,int,dataset
      

  2.   

    我常用的是DataTable,感觉性能还可能呀?
      

  3.   

    对于这个问题,我写了个轻量级的ORM来对实体类进行操作的。需要在实体类中定义Attribute ,指明关联关系,横向扩展字段。目前还在测试 对Oracel的支持中。完毕后会公布源代码。
    但是,我们可以讨论一下思路。就拿实体类来说,例如 A Model 的 B1Code 和 B Model 的 BCode 之间是 many to one 的关系,现在A Model的展示中,需要显示B Model 的BName 属性。那么BName属性对于 A Model 实际映射的数据表,它是不可以参加 修改的。但是 如果 我们在获取 A model数据时,将A,B 之间看成是View table映射 ,在实际修改数据时,只将A Model 映射存在的字段参与修伽,那么这个Model 就同时具备了 ViewModel和Entity Model 2个特性。对于展示 的BName属性 也会在查询中运用!没说清楚,不好意思!
      

  4.   


    哪几个字段有用就取哪几个呀,为何要全取        #region Topic_List
            /// <summary>
            /// 获得主题列表
            /// </summary>
            /// <param name="userid"></param>
            /// <returns></returns>
            public static ArrayList Topic_List(int PageSize, int PageIndex, string  strWhere, ref int counts)
            {
                ArrayList topics = new ArrayList();
                SqlParameter[] parameters = 
                    {
                        Database.MakeInParam("@recordcount", SqlDbType.Int, 4, counts),
        Database.MakeInParam("@QueryStr", SqlDbType.NVarChar, 100, "topics"),
        Database.MakeInParam("@PageSize", SqlDbType.Int, 4, PageSize),
        Database.MakeInParam("@PageCurrent", SqlDbType.Int, 4, PageIndex),
        Database.MakeInParam("@FdShow", SqlDbType.NVarChar, 1000, "id, name,recommend,classification_id, add_time, state, click, picture_id, desktop ,selection,ISNULL((SELECT count(ID) FROM pictures where topic_id=topics.id and delete_tag=0),0) AS picture_count,(select top 1 name from classifications where id=topics.classification_id) as ClassName"),
        Database.MakeInParam("@IdentityStr", SqlDbType.NVarChar, 100, "id"),
        Database.MakeInParam("@WhereStr", SqlDbType.NVarChar, 1000, strWhere),
        Database.MakeInParam("@FdOrder", SqlDbType.NVarChar, 100, "desc")
    };            SqlDataReader dr = null;
                
                Database.RunProc("Common_Page", parameters, out dr);
                try
                {
                    while(dr.Read())
                    {
                        TopicModel topic = new TopicModel();
                        topic.id = (int)dr["id"];
                        topic.name = (string)dr["name"];
                        topic.classname = (string)dr["classname"];
                        topic.classification_id = (int)dr["classification_id"];
                        topic.click = (int)dr["click"];
                        topic.add_time = (DateTime)dr["add_time"];
                        topic.desktop = (bool)dr["desktop"];
                        topic.recommend = (bool)dr["recommend"];
                        topic.selection = (bool)dr["selection"];
                        topic.state = (bool)dr["state"];
                        topic.picture_id = (int)dr["picture_id"];
                        topic.picture_count = (int)dr["picture_count"];
                        topics.Add(topic);
                    }
                    counts = (dr.NextResult() && dr.Read()) ? int.Parse(dr[0].ToString()) : -1;
                }
                finally
                {
                    dr.Close();
                }
                return topics;
            
            }我之前用上面这种形式,你感觉行的话,自己改成泛型好了
      

  5.   

    可以重新考虑设计你的实体bean
      

  6.   

    失学model: 也就是数据表和类的一一对应。 这样的实体 在UI展示的协动性 不好。贫血model: 在对应的数据表上根据关联关系做出的横向扩展。类似于普通的View充血model: 将关联对象作为属性扩展。3类中  :理想的是贫血Model
      

  7.   

    贫血model:   在对应的数据表上根据关联关系做出的横向扩展。类似于普通的View 可以说的详细点吗?或者有没有实现的代码?
      

  8.   

    #region 执行SQL语句,返回记录集ds
            /// <summary>
            /// 执行SQL语句,返回记录集ds
            /// </summary>
            /// <param name="SqlStr">需要执行的SQL语句<param>
            /// <returns>返回语句是否成功</returns>
            public bool RunSql(string SqlStr, out DataSet ds)
            {
                ds = new DataSet();
                this.Open();
                SqlCommand SqlCmd = new SqlCommand(SqlStr, SqlCn);
                SqlDataAdapter adapter = new SqlDataAdapter(SqlCmd);
                try
                {
                    adapter.Fill(ds);
                    return true;
                }
                catch (Exception ex)
                {
                    ds = null;
                    _ErrMessage = ex.Message;
                    return false;
                    //throw new Exception(ex.Message + "\n\n" + SqlStr);
                }
                finally
                {
                    adapter.Dispose();
                    SqlCmd.Dispose();
                    this.Close();
                }        }
            #endregion
      #region 执行不带参数的存储过程
            /// <summary>
            /// 执行不带参数的存储过程
            /// </summary>
            /// <param name="ProcName">存储过程名<param>
            /// <returns>返回存储过程返回值</returns>
            public bool RunProc(string ProcName)
            {
                this.Open();
                SqlCommand SqlCmd = CreateCommand(ProcName, null);
                try
                {
                    SqlCmd.ExecuteNonQuery();                return true;
                }
                catch (Exception ex)
                {
                    _ErrMessage = ex.Message;
                    return false;
                    //throw new Exception(ex.Message);
                }
                finally
                {
                    SqlCmd.Dispose();
                    this.Close();
                }        }        #endregion
            #region 执行带参数的存储过程
            /// <summary>
            /// 执行带参数的存储过程
            /// </summary>
            /// <param name="ProcName">存储过程名<param>
            /// <param name="prams">参数数组<param>
            /// <returns>返回存储过程返回值</returns>
            public bool RunProc(string ProcName, SqlParameter[] prams)
            {            this.Open();
                SqlCommand SqlCmd = CreateCommand(ProcName, prams);
                try
                {
                    SqlCmd.ExecuteNonQuery();
                    return true;
                }
                catch (Exception ex)
                {
                    _ErrMessage = ex.Message;
                    return false;
                    //throw new Exception(ex.Message);
                }            finally
                {
                    SqlCmd.Dispose();
                    this.Close();
                }
            }
            #endregion
      

  9.   

    那IBATIS的示例项目的NPETSHOP MODEL算贫血不是大充血?
      

  10.   

    贫血model:
      事实上就是将model 定义为可能会展示的View Table 的映射,根据配置或驻留的Attribute 解析关系。当然 在执行数据变化操作的时候,贫血model 还是针对原始数据表操作的,对于由关系得来的展示属性,只会参与Query的Action。
      不知道我解释清楚没!  现在我没有代码,晚上可以贴出来。 说错了别怪我!
      

  11.   

    ls的:
    IBATIS 的我没学习过,所以不能准确的回答你的问题。你可以先贴出Model的实现代码,我看看!
      

  12.   

    模型对象的建立namespace Models
    {
        [Serializable]
        [Entity("Models.Departments", "Departments")]
        [EntityID(Hanker.Persistence.Attribute.EntityIDType.Assigned, "DepartNo")]
        public class Departments
        {
            private int departID ;
            [Field("ID", typeof(int),4,true,true)]
            public int DepartID
            {
                get { return departID; }
                set { departID = value; }
            }        private string departName = string.Empty;
            [Field("departName", typeof(string))]
            public string DepartName
            {
                get { return departName; }
                set { departName = value; }
            }        private string  departCode;        [Field("departNo", typeof(int))]
            public string DepartCode
            {
                get { return departCode; }
                set { departCode = value; }
            }
        }  namespace Models
    {
        [Serializable]
        [Entity("Models.Users", "Users")]
        [EntityID(EntityIDType.Identity, "UserCode")]
        public class Users
        {
            private string userCode = string.Empty;
            [Field("UserNo",typeof(string),30,1)]
            public string UserCode
            {
                get { return userCode; }
                set { userCode = value; }
            }        private string userName = string.Empty;
            [Field("UserName",typeof(string),30,2)]
            public string UserName
            {
                get { return userName; }
                set { userName = value; }
            }        private int id;        [Field("ID", typeof(int), 30,true,true)]
            public int Id
            {
                get { return id; }
                set { id = value; }
            }        private string departCode;
            [Field("DepartNo", typeof(string))]
            public string  DepartCode
            {
                get { return departCode; }
                set { departCode = value; }
            }        private string departName = string.Empty;
            [Field("departName", typeof(string),false,false,true)]
            [Relation(typeof(Departments), "DepartCode", RelationType.OneToMany)]
            public string DepartName
            {
                get { return departName; }
                set { departName = value; }
            }        private string address;
            /// <summary>
            /// Field 属性 指定 绑定的数据列,类型,是否自增长类型,是否可以修改,是否视图列
            /// Relation 指定关联的模型,关联模型的属性,以及关联关系
            /// </summary>
            [Field("address", typeof(string), false, false, true)]
            [Relation(typeof(Departments), "DepartCode", RelationType.OneToMany)]
            public string Address
            {
                get { return address; }
                set { address = value; }
            }    }
    }
      

  13.   

    此时的Users 模型 就是一个贫血模型,它扩展了Departs 模型的 DepartName和Address 属性 作为展示。然后,是查询             //获取对象列表
                EntityFactory factory = new EntityFactory();
                ConditionCollection conditions = new ConditionCollection();
                Condition condition = new Condition();
                condition.ColumnName = "DepartName";
                condition.Symbol = SqlCompareSymbol.Equal;
                condition.Value = "Sales";
                conditions.Add(condition);
                List<Users> userList = factory.Query<Users>(conditions);
               
                //获取单个
                  
                user = factory.GetObject<Users>(1);可以看到 扩展的view field 可以参与查询。
    新增/修改/删除            user = new Users();
                user.UserCode = "200001";
                user.UserName = "TestModelORM";
                user.DepartCode = "000002";
                EntityFactory factory = new EntityFactory();
                factory.InsertObject<Users>(user)
                user.UserCode = "200001";
                user.UserName = "TestModel";
                user.DepartCode = "000001";
                EntityFactory factory = new EntityFactory();
                factory.UpdateObject<Users>(user)            user.UserCode = "200001";
                user.UserName = "TestModelORM1";
                EntityFactory factory = new EntityFactory();
                factory.DeleteObject<Users>(user)
    这个时候View field 不会参与上述操作的。由于上述代码中的 EntityFactory 类结合了以前 的组件 Tools.SQL,Tools.DataAccess 所以在这个类里面没有出现SQL-----总觉得没描述清楚,对不起了
      

  14.   

    微软的两个例子:   
      Duwamish使用强类型   
      PetShop   使用自定义实体   
        
     微软自己的实例都用的不一样~~