VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 数据库 > Access数据库 >
  • access数据库之让ADO.NET Entity Framework 支持ACCESS数据(2)

复制代码

在实际的调用过程中,我们使用基本可以和EF使用一样

复制代码
public ActionResult Index()
        {
            int UID = GetUerID();
            List<Door> Arr = new List<Door>();
            try
            {
                // TODO: Add insert logic here
                using (SqlDoorEntities Database = new SqlDoorEntities())
                {
                    //EF写法 
                    //IEnumerable<Door> Records = Database.Door.Where(R => R.U_ID == UID);
                    IEnumerable<Door> Records = Database.Where<Door>(R => R.U_ID == UID);
                    foreach (Door Record in Records) Arr.Add(Record);
                }

            }
            catch (Exception E)
            {
                return Content(E.Message);
            }
            return View(Arr);
        }
复制代码

当然你可以直接用EF的方式 ,缺点就是直接把整个表的数据都读取过来了。下面我依次说说 数据库的 增加 删除 修改;

增加

实现CreateObjectSet,懒人嘛,要不还得去修改。

public IEnumerable<TEntity> CreateObjectSet<TEntity>(string entitySetName) where TEntity : new()
        {
            return  SelectAll<TEntity>();
        }

 

实现AddObject 直接一个简单把对象插入到数组中。实现的时候可以让SaveChanges()在处理

List<object> m_ArrAdd = new List<object>();
public void AddObject(string strName, object o)
        {
            m_ArrAdd.Add(o);
        }

总说SaveChanges()那么先把他贴出来

复制代码
public int SaveChanges()
        {
            if (m_ArrDel.Count > 0)
            {
                DeleteAll();
                m_ArrDel.Clear();
            }
            if (m_ArrAdd.Count > 0)
            {
                AddAll();
                m_ArrAdd.Clear();
            }
            if (m_ArrDetection.Count > 0)
            {
                AutoUpdate();
                m_ArrDetection.Clear();
            }
            m_IsDetectionChange = false;
            return 0;
        }
复制代码

其实也没什么,就是看看数组中哪个有了需要增删改的 就处理下,接着写添加所有的函数。

复制代码
int AddAll()
        {
            foreach (object O in m_ArrAdd)
            {
                AddNew(O);
            }
            return 0;
        }
复制代码

下面该实现我们的insert into 了 直接使用也是可以的 就不用使用纠结的SaveChanges()了。

复制代码
public int AddNew<TEntity>(TEntity TDefault) where TEntity : class
        {
            PropertyInfo[] properties = TDefault.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            PropertyInfo EntityKey = GetEntityKeyFormAllProperty(properties);
            if (EntityKey == null) throw new Exception("未设置主键,无法使用本函数请使用其他函数!");
            string TabName = TDefault.GetType().Name;
            string EntityValue = "";
            string strRows = "";
            string strValues = "";
            #region Rows Values
            foreach (PropertyInfo Info in properties)
            {
                object ce = Info.GetValue(TDefault, null);
                string strLeft = Info.Name;
                string strRight = "";
                if (ce == null)
                    continue;
                else if (ce is DateTime)
                    strRight = string.Format("#{0}#", ce.ToString());
                else if (ce is ValueType)
                    strRight = ce.ToString();
                else if (ce is ValueType)
                    strRight = ce.ToString();
                else if (ce is string || ce is char)
                    strRight = string.Format("'{0}'", ce.ToString());
                if (strLeft == EntityKey.Name)
                {
                    EntityValue = strRight;
                    continue;
                }
                if (strRight.Length == 0) continue;
                if (strLeft == "EntityKey" || strLeft == "EntityState") continue;
                strRows = strRows + strLeft + ",";
                strValues = strValues + strRight + ",";
            }
            #endregion
            if (strRows.Length < 2 || strValues.Length < 2) throw new Exception("SQL语句错误");
            strRows = strRows.Remove(strRows.Length - 1);
            strValues = strValues.Remove(strValues.Length - 1);
            string strSqlQuery = string.Format("INSERT INTO {0} ({1}) VALUES ({2})", TabName, strRows, strValues);
            m_LastSqlCommand = strSqlQuery;
            try
            {
                OleDbCommand Cmd = new OleDbCommand(strSqlQuery, AccessConn);
                Cmd.ExecuteNonQuery();
            }
            catch (Exception)
            {
                throw;
            }
            return 0;
        }
复制代码

函数中也没什么,就是注意一下不要生成SQL语句的时候,把主键信息也生成进去,一般情况主键大多是个自动增长的数字吧。还有就是不要把EntityObject的属性的特有主键信息写入到数据库中。根据反射写入数据库。

删除

还是先现实EF的删除方法DeleteObject

复制代码
public void DeleteObject(object TDefault)
        {
            PropertyInfo[] properties = TDefault.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            PropertyInfo EntityKey = GetEntityKeyFormAllProperty(properties);
            if (EntityKey == null) throw new Exception("未设置主键,无法使用本函数请使用其他函数!");
            string EntityValue = EntityKey.GetValue(TDefault, null).ToString();
            if (EntityValue == null || EntityValue == "") throw new Exception("反射取值失败!");
            string entitySetName = TDefault.GetType().Name;
            string KeyName = TDefault.GetType().Name;
            if (!m_ArrDel.ContainsKey(KeyName)) m_ArrDel.Add(KeyName,new List<string>());
            m_ArrDel[KeyName].Add(string.Format("(({0})={1})", EntityKey.Name, EntityValue));
        }
复制代码

然后我们需要建立我们自己的列表

Dictionary<string, List<string>> m_ArrDel = new Dictionary<string, List<string>>();

 

实现删除函数

复制代码
public int Delete<TEntity>(TEntity TDefault)
        {
            PropertyInfo[] properties = TDefault.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            PropertyInfo EntityKey = GetEntityKeyFormAllProperty(properties);
            if (EntityKey == null) throw new Exception("未设置主键,无法使用本函数请使用其他函数!");
            string EntityValue = EntityKey.GetValue(TDefault, null).ToString();
            if (EntityValue == null || EntityValue == "") throw new Exception("反射取值失败!");
            string entitySetName = TDefault.GetType().Name;
            string strSqlQuery = string.Format("DELETE FROM {0} WHERE {1}={2} ", entitySetName, EntityKey, EntityValue);
            m_LastSqlCommand = strSqlQuery;
            try
            {
                OleDbCommand Cmd = new OleDbCommand(strSqlQuery, AccessConn);
                Cmd.ExecuteNonQuery();
            }
            catch (Exception)
            {
                throw;
            }
            return 0;
        }
复制代码

更新

这里是根据主键更新的,没有实现update …where…,因为往往都是查询到记录,然后根据这个记录更新的,所以还需要更多代码的实现Select等,为了这个小的项目进度没有写完。上面代码已经告诉了,可以侦测到查询到的属性的变更所以SaveChanges()保存更改时,我们就直接根据数组进行更改了。

复制代码
public int AutoUpdate()
        {
            List<string> ArrSqlText = new List<string>();
            foreach (KeyValuePair<string, Dictionary<string, Dictionary<string, object[]>>> TabKVP in m_ArrDetection)
            {
                //遍历表名
                string TabName = TabKVP.Key;
                foreach (KeyValuePair<string, Dictionary<string, object[]>> KeyKVP in TabKVP.Value)
                {
                    string strSet = "";
                    string strMainKeyName = "";
                    #region 把数据列出来例如: a=1,c="2"
                    foreach (KeyValuePair<string, object[]> ValueKVP in KeyKVP.Value)
                    {
                        if (strMainKeyName.Length == 0) strMainKeyName = ValueKVP.Value[1].ToString();
                        object Va = ValueKVP.Value[0];
                        string strLeft = ValueKVP.Key;
                        string strRight = "";
                        #region 根据值确认是否添加引号
                        if (ValueKVP.Value == null)
                            continue;
                        else if (Va is DateTime)
                            strRight = string.Format("#{0}#", Va.ToString());
                        else if (Va is ValueType)
                            strRight = Va.ToString();
                        else if (Va is string || Va is char)
                            strRight = string.Format("'{0}'", Va.ToString());
                        #endregion
                        if (strRight.Length == 0) continue;
                        if (strLeft == "EntityKey" || strLeft == "EntityState") continue;
                        strSet += strLeft + "=" + strRight + ",";

                    }
                    #endregion
                    if (strSet.Length < 2) continue;
                    strSet = strSet.Remove(strSet.Length - 1);
                    //根据当前的主键[ID] 生成一个SQL语句
                    string strSqlQuery = string.Format("UPDATE {0} SET {1} WHERE {2}={3} ", TabName, strSet, strMainKeyName, KeyKVP.Key);
                    ArrSqlText.Add(strSqlQuery);
                }
            }
            foreach (string strSqlQuery in ArrSqlText)
            {
                m_LastSqlCommand = strSqlQuery;
                try
                {
                    OleDbCommand Cmd = new OleDbCommand(strSqlQuery, AccessConn);
                    Cmd.ExecuteNonQuery();
                }
                catch
                {
                }

            }
            return 0;
        }
复制代码

当然我们还有直接把对象直接赋值拷贝的时候( a = b),这时候是侦测不到属性的变化的,所以我们要另外一个函数来支持更新,就是让他实现侦测到属性的变化。

复制代码
public void CopyPropertiesFrom(object destObject, object sourceObject)
        {
            if (destObject.GetType().Name != destObject.GetType().Name) throw new Exception("类型不同");
            PropertyInfo[] destProperties = destObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            PropertyInfo[] sourceProperties = sourceObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            PropertyInfo EntityKey = GetEntityKeyFormAllProperty(destProperties);
            if (EntityKey == null) throw new Exception("未设置主键,无法使用本函数请使用其他函数!");
            
            for (int i = 0; i < destProperties.Length; i++)
            {
                if (destProperties[i]==null|| destProperties[i].Name == EntityKey.Name) continue;
                if (destProperties[i].Name == "EntityKey" || destProperties[i].Name == "EntityState") continue;
                object DstV = destProperties[i].GetValue(destObject,null);
                object SrcV = sourceProperties[i].GetValue(sourceObject, null);
                if (SrcV == null) continue;//源 是NULL 不拷贝
                if (DstV.ToString() == SrcV.ToString()) continue;
                destProperties[i].SetValue(destObject, SrcV,null);
                //Action<object, object> LmdSetProp = LmdSet(destObject.GetType(), destProperties[i].Name);
                //LmdSetProp(destObject, SrcV);
            }

        }
复制代码

显示-添加-删除-修改的例子代码

复制代码
#region 显示用户
        [Authorize(Roles = "manager")]
        public ActionResult Index()
        {
            List<Users> Users = new List<Users>();
            Users u = new Users();
            try
            {
                using (SqlDoorEntities Database = new SqlDoorEntities())
                {
                    IEnumerable<Users> Records = Database.Users;
                    if (Records.Count() > 0)
                    {
                        foreach (Users U in Records) Users.Add(U);
                    }
                }
            }
            catch { }
            return View(Users);
        }
        #endregion

        #region 创建用户
        [Authorize(Roles = "manager")]
        [HttpPost]
        public ActionResult CreateUser(Users collection)
        {
            try
            {
                // TODO: Add insert logic here
                using (SqlDoorEntities Database = new SqlDoorEntities())
                {
                    IEnumerable<Users> Records = Database.Where<Users>(R => R.U_Number == collection.U_Number);
                    if (Records.Count() > 0)
                    {
                        ModelState.AddModelError("", "已經有了記錄了!");
                        return RedirectToAction("Index");
                    }
                    Database.AddToUsers(collection);
                    Database.SaveChanges();
                    //collection.U_LastIP = GetWebClientIp();
                }
                return RedirectToAction("Index");
            }
            catch (Exception E)
            {
                ModelState.AddModelError("", "数据库错误!" + E.Message);
            }
            return View();
        }
        [Authorize(Roles = "manager")]
        public ActionResult CreateUser()
        {
            return View();
        }
        #endregion

        #region 编辑用户
        [Authorize(Roles = "manager")]
        [HttpPost]
        public ActionResult EditUser(int id, Users collection)
        {
            try
            {
                // TODO: Add insert logic here
                
                using (SqlDoorEntities Database = new SqlDoorEntities())
                {
                    Users Record = Database.Where<Users>(R => R.U_ID == id).FirstOrDefault();
                    //Database.Update<Users>(Record);
                    Database.CopyPropertiesFrom(Record, collection);
                    Database.SaveChanges();
                }
                return Content("OK");
            }
            catch (Exception E)
            {
                return Content(E.Message);
            }
        }
        #endregion

        #region 删除用户
        [Authorize(Roles = "manager")]
        public ActionResult DeleteUser(int id)
        {
            try
            {
                // TODO: Add insert logic here

                using (SqlDoorEntities Database = new SqlDoorEntities())
                {
                    Users Record = Database.Where<Users>(R => R.U_ID == id).FirstOrDefault();
                    if (User != null)
                    {
                        Database.DeleteObject(Record);
                        Database.SaveChanges();
                    }
                }
            }
            catch
            {

            }
            return RedirectToAction("Index");
        }
        #endregion
复制代码

最后

算是写完了,也算是我cnblog的第一篇技术类文章吧。写的不对的地方欢迎指正啊。本人QQ78486367。下面是用到的源文件。

http://files.cnblogs.com/hackdragon/EFToAccess.zip

相关教程
          
关于我们--广告服务--免责声明--本站帮助-友情链接--版权声明--联系我们       黑ICP备07002182号