大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C#技巧 > 让ADO.NET Entity Framework 支持AC

让ADO.NET Entity Framework 支持AC(4)

关键词:数据库.NETADOEntity  阅读(1893) 赞(16)

[摘要]本文是对让ADO.NET Entity Framework 支持ACCESS数据库的讲解,与大家分享。

private bool IsEntityKeyProperty(PropertyInfo Info)
        {
            foreach (Attribute attr in Attribute.GetCustomAttributes(Info))
            {
                if (attr is System.Data.Objects.DataClasses.EdmScalarPropertyAttribute)
                {
                    System.Data.Objects.DataClasses.EdmScalarPropertyAttribute Key = (System.Data.Objects.DataClasses.EdmScalarPropertyAttribute)attr;
                    if (Key.EntityKeyProperty == true)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        private PropertyInfo GetEntityKeyFormAllProperty(PropertyInfo[] properties)
        {
            foreach (PropertyInfo Info in properties)
            {
                if (IsEntityKeyProperty(Info)) return Info;
            }
            return null;
        }

在实际的调用过程中,我们使用基本可以和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()保存更改时,我们就直接根据数组进行更改了。



相关评论