<rp id="wnpn7"><ruby id="wnpn7"></ruby></rp>
<progress id="wnpn7"><track id="wnpn7"><rt id="wnpn7"></rt></track></progress>
<ruby id="wnpn7"></ruby>
<ruby id="wnpn7"><blockquote id="wnpn7"><div id="wnpn7"></div></blockquote></ruby>

    1. <em id="wnpn7"><ruby id="wnpn7"><input id="wnpn7"></input></ruby></em>
      1. <button id="wnpn7"><acronym id="wnpn7"></acronym></button><button id="wnpn7"><acronym id="wnpn7"></acronym></button>

        <rp id="wnpn7"><acronym id="wnpn7"></acronym></rp>

        <li id="wnpn7"><object id="wnpn7"><u id="wnpn7"></u></object></li>
        VB.net 2010 視頻教程 VB.net 2010 視頻教程 python基礎視頻教程
        SQL Server 2008 視頻教程 c#入門經典教程 Visual Basic從門到精通視頻教程
        當前位置:
        首頁 > 數據庫 > Access數據庫 >
        • access數據庫之讓ADO.NET Entity Framework 支持ACCESS數據

         

        如寫的不好請見諒,本人水平有限。

        個人簡歷及水平:。 http://www.cnblogs.com/hackdragon/p/3662599.html

        接到一個程序和網頁交互的項目,用ADO.NET Entity Framework (以下簡稱EF)很快就搞完了,但是對方的空間提供的MSSQL數據庫比較昂貴,所以就采用ACCESS數據庫,但是我查了資料發現 EF不支持Access數據庫,(以前覺得LINQ TO SQL 不支持 這個應該支持),寫完的代碼不想用OLEDB在寫了,于是網上一頓查,試驗了ALINQ和其他很多的,總是不能符合項目的需要。不是更新不行就算插入失敗,要不就是經常查詢錯誤。最后沒辦法,我自己決定寫一個實體支持ACCESS數據庫,我覺得懶人應該有需要這個的,當然大俠們估計有更好的辦法來更懶一些。

        懶人第一步:

        因為VS的實體生成器不支持ACCESS數據庫,所以無法生成代碼,但是想快速開發項目,那么你可以用SQL數據庫先來設計,然后導出數據庫到ACCESS數據庫,這樣做的目的是讓生成器可以生成我們所需要的代碼。注意設計數據庫字段的時候要考慮他們的兼容性。

        勤快第二步:

        開始寫代碼了,原始的上下文代碼如下:

        復制代碼
        #region 上下文
            
            /// <summary>
            /// 沒有元數據文檔可用。
            /// </summary>
            public partial class SqlDoorEntities1 : ObjectContext
            {
                #region 構造函數
            
                /// <summary>
                /// 請使用應用程序配置文件的“SqlDoorEntities1”部分中的連接字符串初始化新 SqlDoorEntities1 對象。
                /// </summary>
                public SqlDoorEntities1() : base("name=SqlDoorEntities1", "SqlDoorEntities1")
                {
                    OnContextCreated();
                }
            
                /// <summary>
                /// 初始化新的 SqlDoorEntities1 對象。
                /// </summary>
                public SqlDoorEntities1(string connectionString) : base(connectionString, "SqlDoorEntities1")
                {
                    OnContextCreated();
                }
            
                /// <summary>
                /// 初始化新的 SqlDoorEntities1 對象。
                /// </summary>
                public SqlDoorEntities1(EntityConnection connection) : base(connection, "SqlDoorEntities1")
                {
                    OnContextCreated();
                }
            
                #endregion
            
                #region 分部方法
            
                partial void OnContextCreated();
            
                #endregion
            
                #region ObjectSet 屬性
            
                /// <summary>
                /// 沒有元數據文檔可用。
                /// </summary>
                public ObjectSet<CmdMsg> CmdMsg
                {
                    get
                    {
                        if ((_CmdMsg == null))
                        {
                            _CmdMsg = base.CreateObjectSet<CmdMsg>("CmdMsg");
                        }
                        return _CmdMsg;
                    }
                }
                private ObjectSet<CmdMsg> _CmdMsg;
            
                /// <summary>
                /// 沒有元數據文檔可用。
                /// </summary>
                public ObjectSet<Door> Door
                {
                    get
                    {
                        if ((_Door == null))
                        {
                            _Door = base.CreateObjectSet<Door>("Door");
                        }
                        return _Door;
                    }
                }
                private ObjectSet<Door> _Door;
            
                /// <summary>
                /// 沒有元數據文檔可用。
                /// </summary>
                public ObjectSet<Manager> Manager
                {
                    get
                    {
                        if ((_Manager == null))
                        {
                            _Manager = base.CreateObjectSet<Manager>("Manager");
                        }
                        return _Manager;
                    }
                }
                private ObjectSet<Manager> _Manager;
            
                /// <summary>
                /// 沒有元數據文檔可用。
                /// </summary>
                public ObjectSet<Users> Users
                {
                    get
                    {
                        if ((_Users == null))
                        {
                            _Users = base.CreateObjectSet<Users>("Users");
                        }
                        return _Users;
                    }
                }
                private ObjectSet<Users> _Users;
        
                #endregion
        
                #region AddTo 方法
            
                /// <summary>
                /// 用于向 CmdMsg EntitySet 添加新對象的方法,已棄用。請考慮改用關聯的 ObjectSet&lt;T&gt; 屬性的 .Add 方法。
                /// </summary>
                public void AddToCmdMsg(CmdMsg cmdMsg)
                {
                    base.AddObject("CmdMsg", cmdMsg);
                }
            
                /// <summary>
                /// 用于向 Door EntitySet 添加新對象的方法,已棄用。請考慮改用關聯的 ObjectSet&lt;T&gt; 屬性的 .Add 方法。
                /// </summary>
                public void AddToDoor(Door door)
                {
                    base.AddObject("Door", door);
                }
            
                /// <summary>
                /// 用于向 Manager EntitySet 添加新對象的方法,已棄用。請考慮改用關聯的 ObjectSet&lt;T&gt; 屬性的 .Add 方法。
                /// </summary>
                public void AddToManager(Manager manager)
                {
                    base.AddObject("Manager", manager);
                }
            
                /// <summary>
                /// 用于向 Users EntitySet 添加新對象的方法,已棄用。請考慮改用關聯的 ObjectSet&lt;T&gt; 屬性的 .Add 方法。
                /// </summary>
                public void AddToUsers(Users users)
                {
                    base.AddObject("Users", users);
                }
        
                #endregion
        
            }
        
            #endregion
        復制代碼

        ObjectContext 繼承于IDisposable 那么我寫一個自己的 ObjectContext 這樣的類 我給他起個名字叫EFToAccess 那么多 構造方法 我們就需要2個一個 是 給定的連接字符串 一個是默認從webconfig中讀取的鏈接字符串就可以了。本人偷懶,直接讀取指定的路徑了。數據庫的簡單讀寫可能都依賴一個where查詢,那么怎么實現自己的where查詢就很關鍵,于是我看資料研究了2天Lambda Expression 表達式。最后還是看了 博客園的一篇 擴展LINQ to SQL:使用Lambda Expression批量刪除數據才會用,現在也不是很明白,懶人就是拿來主義,不怎么消化,我現在也沒多少時間消化知識,估計這樣的人也不少吧。下面是我自己用的的方法,利用VS生成的代碼 2個替換1個刪除搞定 (ObjectContext替換“你自己的類名我的是SqlDoorEntities”,ObjectSet替換成IEnumerable,刪除無用的構造函數)

        復制代碼
        public class SqlDoorEntities : EFToAccess
            {
                public SqlDoorEntities():base("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" 
        +AppDomain.CurrentDomain.BaseDirectory + "bin\\DataDoor.mdb")
        
                {
                }
                #region IEnumerable 屬性
                /// <summary>
                /// 沒有元數據文檔可用。
                /// </summary>
        
                public IEnumerable<CmdMsg> CmdMsg
                {
                    get
                    {
                        if ((_CmdMsg == null))
                        {
                            _CmdMsg = base.CreateObjectSet<CmdMsg>("CmdMsg");
                        }
                        return _CmdMsg;
                    }
                }
                private IEnumerable<CmdMsg> _CmdMsg;
        
                /// <summary>
                /// 沒有元數據文檔可用。
                /// </summary>
                public IEnumerable<Door> Door
                {
                    get
                    {
                        if ((_Door == null))
                        {
                            _Door = base.CreateObjectSet<Door>("Door");
                        }
                        return _Door;
                    }
                }
                private IEnumerable<Door> _Door;
        
                /// <summary>
                /// 沒有元數據文檔可用。
                /// </summary>
                public IEnumerable<Manager> Manager
                {
                    get
                    {
                        if ((_Manager == null))
                        {
                            _Manager = base.CreateObjectSet<Manager>("Manager");
                        }
                        return _Manager;
                    }
                }
                private IEnumerable<Manager> _Manager;
        
                /// <summary>
                /// 沒有元數據文檔可用。
                /// </summary>
                public IEnumerable<Users> Users
                {
                    get
                    {
                        if ((_Users == null))
                        {
                            _Users = base.CreateObjectSet<Users>("Users");
                        }
                        return _Users;
                    }
                }
                private IEnumerable<Users> _Users;
        
                #endregion
                #region AddTo 方法
        
                /// <summary>
                /// 用于向 CmdMsg EntitySet 添加新對象的方法,已棄用。請考慮改用關聯的 IEnumerable&lt;T&gt; 屬性的 .Add 方法。
                /// </summary>
                public void AddToCmdMsg(CmdMsg cmdMsg)
                {
                    base.AddObject("CmdMsg", cmdMsg);
                }
        
                /// <summary>
                /// 用于向 Door EntitySet 添加新對象的方法,已棄用。請考慮改用關聯的 IEnumerable&lt;T&gt; 屬性的 .Add 方法。
                /// </summary>
                public void AddToDoor(Door door)
                {
                    base.AddObject("Door", door);
                }
        
                /// <summary>
                /// 用于向 Manager EntitySet 添加新對象的方法,已棄用。請考慮改用關聯的 IEnumerable&lt;T&gt; 屬性的 .Add 方法。
                /// </summary>
                public void AddToManager(Manager manager)
                {
                    base.AddObject("Manager", manager);
                }
        
                /// <summary>
                /// 用于向 Users EntitySet 添加新對象的方法,已棄用。請考慮改用關聯的 IEnumerable&lt;T&gt; 屬性的 .Add 方法。
                /// </summary>
                public void AddToUsers(Users users)
                {
                    base.AddObject("Users", users);
                }
        
                #endregion
            }
        復制代碼

        懶人第三步:

        為了讓代碼和EF使用方法基本一致,所以不得不做一些工作讓我寫的類基本滿足項目需要。首先實現一個讓Lambda Expression 表達式變成字符串的函數

        復制代碼
        string GetWhereString(Expression Func)
                {
                    ConditionBuilder conditionBuilder = new ConditionBuilder();
                    conditionBuilder.Build(Func);
                    for (int i = 0; i < conditionBuilder.Arguments.Length; i++)
                    {
                        object ce = conditionBuilder.Arguments[i];
                        if (ce == null)
                            conditionBuilder.Arguments[i] = "null";
                        else if (ce is ValueType)
                            conditionBuilder.Arguments[i] = ce.ToString();
                        else if (ce is string || ce is char)
                            conditionBuilder.Arguments[i] = string.Format("'{0}'", ce.ToString());
                        else if (ce is DateTime)
                            conditionBuilder.Arguments[i] = string.Format("#{0}#", ce.ToString());
        
                    }
                    return string.Format(conditionBuilder.Condition, conditionBuilder.Arguments);
                }
        復制代碼

        上面的ConditionBuilder類代碼我就不貼出了。大家參考我提到的那篇文章,如果實際應用當中,有死循環的地方那么應該在該調用基類的地方加入base.XXX比如base.Visit

        實現我們自己的where 這里如果我們自己生成類 那么我們的實體類類可以直接有一個where 方法,但是我為了能讓我們懶人使用VS生成的實體類只能這么實現了。為了代碼利用率,我們還需要另外2個函數。

        取得所有記錄

        復制代碼
        IEnumerable<TEntity> SelectAll<TEntity>() where TEntity : new()
                {
                    TEntity TDefault = new TEntity();
                    string entitySetName = TDefault.GetType().Name;
                    string strSqlQuery = string.Format("SELECT * FROM {0}", entitySetName);
                    m_LastSqlCommand = strSqlQuery;
                    return SelectWhere<TEntity>(strSqlQuery);
                }
        復制代碼

        經常的條件查詢

        復制代碼
        public IEnumerable<TEntity> Where<TEntity>(Expression<Func<TEntity, bool>> Func) where TEntity : new()
                {
                    TEntity TDefault = new TEntity();
                    string entitySetName = TDefault.GetType().Name;
                    string strWhere = GetWhereString(Func).Replace("Where", entitySetName);
                    string strSqlQuery = string.Format("SELECT * FROM {0} WHERE {1} ", entitySetName, strWhere);
                    m_LastSqlCommand = strSqlQuery;
                    return SelectWhere<TEntity>(strSqlQuery);
                }
        復制代碼

        最后的where

        復制代碼
        IEnumerable<TEntity> SelectWhere<TEntity>(string strSqlQuery) where TEntity : new()
                {
                    TEntity TDefault = new TEntity();
                    //確認基礎類型是否是 EntityObject類型
                    Type TBase = TDefault.GetType();
                    while ((TBase.BaseType) != null)
                    {
                        if (TBase.Name == "EntityObject") break;
                        TBase = TBase.BaseType;
                    }
                    bool IsPCEH = false;
                    if (TBase != null && TBase.Name == "EntityObject")  IsPCEH = true;
                    PropertyInfo[] properties = TDefault.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
                    List<TEntity> Records = new List<TEntity>();
                    string entitySetName = TDefault.GetType().Name;
                    try
                    {
                        OleDbCommand Cmd = new OleDbCommand(strSqlQuery, AccessConn);
                        OleDbDataReader sqlReader = Cmd.ExecuteReader();
                        #region 數據庫查詢開始
                        while (sqlReader.Read())
                        {
                            TEntity TValue = new TEntity();
                            //輸入是EntityObject類型,那么加入屬性改變事件
                            if (IsPCEH)
                            {
                                EntityObject EO = TValue as EntityObject;
                                EO.PropertyChanged += PropertyChangedEH;
                            }
                            for (int i = 0; i < sqlReader.FieldCount; i++)
                            {
                                string strField = sqlReader.GetName(i);
                                //根據字段名 反射 類的屬性
                                PropertyInfo p = properties.Where(P => string.Compare(P.Name, strField, true) == 0).First();
                                #region 數據轉換
                                switch (p.PropertyType.Name.ToString().ToLower())
                                {
                                    case "int16":
                                        if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetInt16(i), null);
                                        break;
                                    case "int32":
                                        if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetInt32(i), null);
                                        break;
                                    case "int64":
                                        if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetInt64(i), null);
                                        break;
                                    case "string":
                                        if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetString(i), null);
                                        break;
                                    case "double":
                                        if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetDouble(i), null);
                                        break;
                                    case "float":
                                        if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetFloat(i), null);
                                        break;
                                    case "decimal":
                                        if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetDecimal(i), null);
                                        break;
                                    case "datetime":
                                        if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetDateTime(i), null);
                                        break;
                                    default:
                                        if (!sqlReader.IsDBNull(i)) p.SetValue(TValue, sqlReader.GetValue(i), null);
                                        break;
                                }
                                #endregion
        
                            }
                            Records.Add(TValue);
                        }
                        #endregion
                        Cmd.Clone();
                        m_IsDetectionChange = true;
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                    return Records;
                }
        復制代碼

        屬性的改變(也就是數據庫記錄的字段值)我們要知道才能實現EF的SaveChanges()函數那么我們需要簡歷一個數組變量,直接上代碼

        //表名            //主鍵              //屬性    值1 值2 主鍵類型名字
                Dictionary<string, Dictionary<string, Dictionary<string, object[]>>> m_ArrDetection = new Dictionary<string, Dictionary<string, Dictionary<string, object[]>>>();
        
        復制代碼
        void PropertyChangedEH(object sender, PropertyChangedEventArgs e)
                {
                    //沒有開啟返回
                    if (!m_IsDetectionChange) return;
                    //反射所有屬性
                    PropertyInfo[] properties = sender.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
                    //查詢主鍵
                    PropertyInfo EntityKey = GetEntityKeyFormAllProperty(properties);
                    //沒有主鍵的返回(表必須要有主鍵)
                    if (EntityKey == null) return;
                    //表名字
                    string Table = sender.GetType().Name;
                    //主鍵值
                    string MainKey = EntityKey.GetValue(sender, null).ToString();
                    if (MainKey == null || MainKey == "") return;
                    //沒有表 就添加
                    if (!m_ArrDetection.ContainsKey(Table)) m_ArrDetection[Table] = new Dictionary<string, Dictionary<string, object[]>>();
                    //沒有主鍵 就添加
                    if (!m_ArrDetection[Table].ContainsKey(MainKey)) m_ArrDetection[Table][MainKey] = new Dictionary<string, object[]>();
                    //主鍵是不用更新的(一般數據庫主鍵都是自動增長的吧,尤其快速開發的項目)
                    if (e.PropertyName == MainKey) return;
                    PropertyInfo p = properties.Where(P => string.Compare(P.Name, e.PropertyName, true) == 0).First();
                    //賦值
                    m_ArrDetection[Table][MainKey][e.PropertyName] = new object[2] { p.GetValue(sender, null), EntityKey.Name };
                }
        復制代碼

        查找主鍵的函數

        復制代碼
        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;
                }
              
        
        相關教程
                
        免费看成年人视频大全_免费看成年人视频在线观看