1. 程式人生 > >ORM框架學習之EF

ORM框架學習之EF

pla cep serve hang linq cor lis remove adapter


首先推薦一篇很好的EF文章翻譯,可以系統的學習一遍。
《Entity Framework 6 Recipes》中文翻譯系列

EF使用體會

優點:

  • 可以省去Ado.net復雜的管道連接代碼。
  • 通過簡單的引用就能完成對數據庫的連接和開發。
  • 可以省去一些SQL語句的編寫,對一些底層可能需要適配多數據庫提供了一些方便。

缺點:

  • 學習成本較高,如果不怎麽懂SQL,索引的一些數據庫知識,也寫不太好相對優化的Linq查詢,所有EF既要懂Sql又懂Linq是最好的。
  • 比較大,EF的dll默認是連接SqlServer若要連接其它數據庫引用其它數據庫的DLL加起來10幾M,而像Dapper這樣的輕量級框架才100多K。
  • 查詢只支持數據結果對實體的轉換,不支持DataTable。

資料匯總

EF連接

連接數據庫的多種方法

EF配置

EF的霸氣配置秒殺一切

EF進階

1.學習LINQ To Sql

LINQ To Sql語法匯總

2.學習Expression

LINQ Expression高級篇

3.優化測試

EF查詢百萬級數據的性能測試

簡單的類庫

項目如圖:
技術分享圖片

Data.Map中放相關的EntityTypeConfiguration
Data.Module中相關的實體

這裏貼一下EFContext和EFDatabase的類

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;


namespace Data.EF
{
    //[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]  Mysql數據庫配置
    public class EFContext : DbContext, IDisposable
    {
        public EFContext(string dbName)
            : base(dbName)
        {
            Database.SetInitializer<EFContext>(null);
            this.Configuration.AutoDetectChangesEnabled = false;
            this.Configuration.ValidateOnSaveEnabled = false;
            this.Configuration.LazyLoadingEnabled = false;
            this.Configuration.ProxyCreationEnabled = false;
        }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            string assembleFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("Data.EF.DLL", "Data.Map.dll").Replace("file:///", "");
            Assembly asm = Assembly.LoadFile(assembleFileName);
            var typesToRegister = asm.GetTypes()
            .Where(type => !String.IsNullOrEmpty(type.Namespace))
            .Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.Configurations.Add(configurationInstance);
            }
            base.OnModelCreating(modelBuilder);
        }
    }

}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace Data.EF
{
    public class EFDatabase
    {
        /// <summary>
        /// 返回字符集
        /// </summary>
        /// <typeparam name="Table"></typeparam>
        /// <returns></returns>
        public DbSet<Table> Set<Table>() where Table : class
        {
            return dbcontext.Set<Table>();
        }

        #region 屬性
        /// <summary>
        /// 獲取 當前使用的數據訪問上下文對象
        /// </summary>
        public DbContext dbcontext { get; set; }
        /// <summary>
        /// 事務對象
        /// </summary>
        public DbTransaction dbTransaction { get; set; }

        #endregion

        #region 構造函數

        public EFDatabase(string dataBase)
        {
            dbcontext = new EFContext(dataBase);
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 獲取實體類鍵值(緩存)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        private static Hashtable GetPropertyInfo<T>(T entity)
        {
            Type type = entity.GetType();
            object CacheEntity = null;
            if (CacheEntity == null)
            {
                Hashtable ht = new Hashtable();
                PropertyInfo[] props = type.GetProperties();
                foreach (PropertyInfo prop in props)
                {
                    string name = prop.Name;
                    object value = prop.GetValue(entity, null);
                    ht[name] = value;
                }
                return ht;
            }
            else
            {
                return (Hashtable)CacheEntity;
            }
        }

        /// <summary>
        /// 存儲過程語句
        /// </summary>
        /// <param name="procName">存儲過程名稱</param>
        /// <param name="dbParameter">執行命令所需的sql語句對應參數</param>
        /// <returns></returns>
        private static string BuilderProc(string procName, params DbParameter[] dbParameter)
        {
            StringBuilder strSql = new StringBuilder("exec " + procName);
            if (dbParameter != null)
            {
                foreach (var item in dbParameter)
                {
                    strSql.Append(" " + item + ",");
                }
                strSql = strSql.Remove(strSql.Length - 1, 1);
            }
            return strSql.ToString();
        }

        private int Delete<T>(T entity) where T : class
        {
            dbcontext.Set<T>().Attach(entity);
            dbcontext.Set<T>().Remove(entity);
            return dbTransaction == null ? dbcontext.SaveChanges() : 0;
        }

        private int Delete<T>(IEnumerable<T> entities) where T : class
        {
            foreach (var entity in entities)
            {
                dbcontext.Set<T>().Attach(entity);
                dbcontext.Set<T>().Remove(entity);
            }
            return dbTransaction == null ? dbcontext.SaveChanges() : 0;
        }

        #endregion

        public EFDatabase BeginTrans()
        {
            DbConnection dbConnection = ((IObjectContextAdapter)dbcontext).ObjectContext.Connection;
            if (dbConnection.State == ConnectionState.Closed)
            {
                dbConnection.Open();
            }
            dbTransaction = dbConnection.BeginTransaction();
            return this;
        }

        public int Commit()
        {
            try
            {
                int returnValue = dbcontext.SaveChanges();
                if (dbTransaction != null)
                {
                    dbTransaction.Commit();
                    this.Close();
                }
                return returnValue;
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null )
                {
                    throw ex.InnerException;
                }
                throw;
            }
            finally
            {
                if (dbTransaction == null)
                {
                    this.Close();
                }
            }
        }

        public void Rollback()
        {
            this.dbTransaction.Rollback();
            this.dbTransaction.Dispose();
            this.Close();
        }

        public void Close()
        {
            dbcontext.Dispose();
        }

        public int ExecuteBySql(string strSql)
        {
            dbcontext.Database.CommandTimeout = 60;
            return dbcontext.Database.ExecuteSqlCommand(strSql);
        }

        public int ExecuteBySql(string strSql, params object[] dbParameter)
        {
            dbcontext.Database.CommandTimeout = 60;
            return dbcontext.Database.ExecuteSqlCommand(strSql, dbParameter);
        }

        public int ExecuteByProc(string procName)
        {
              return dbcontext.Database.ExecuteSqlCommand(BuilderProc(procName));
        }

        public int ExecuteByProc(string procName, System.Data.Common.DbParameter[] dbParameter)
        {
              return dbcontext.Database.ExecuteSqlCommand(BuilderProc(procName, dbParameter), dbParameter);
        }

        public T FindEntity<T>(object keyValue) where T : class
        {
            return dbcontext.Set<T>().Find(keyValue);
        }

        public T FindEntity<T>(Expression<Func<T, bool>> condition) where T : class, new()
        {
              return dbcontext.Set<T>().Where(condition).FirstOrDefault();
        }

        public IQueryable<T> FindList<T>(Expression<Func<T, bool>> condition) where T : class, new()
        {
            return dbcontext.Set<T>().Where(condition);
        }

        public IQueryable<T> FindList<T>(string strSql) where T : class
        {
            return dbcontext.Set<T>().SqlQuery(strSql).AsQueryable();
        }

        public IQueryable<T> FindList<T>(string strSql, DbParameter[] dbParameter) where T : class
        {
            return dbcontext.Set<T>().SqlQuery(strSql, dbParameter).AsQueryable();
        }

        public int Delete<T>(object propertyValue, string propertyName) where T : class
        {
              string TableName = typeof(T).Name;
              return this.ExecuteBySql("delete from " + TableName + " where " + propertyName + " = {0}", propertyValue);
        }

        public int Delete<T>(Expression<Func<T, bool>> condition) where T : class, new()
        {
            IEnumerable<T> entities = dbcontext.Set<T>().Where(condition).ToList();
            return entities.Count() > 0 ? Delete(entities) : 0;
        }

        public int Update<T>(T entity) where T : class
        {
            dbcontext.Set<T>().Attach(entity);
            Hashtable props = GetPropertyInfo<T>(entity);
            foreach (string item in props.Keys)
            {
                object value = dbcontext.Entry(entity).Property(item).CurrentValue;
                if (value != null)
                {
                    if (value.ToString() == "&nbsp;"||value.ToString().Trim()=="")
                        dbcontext.Entry(entity).Property(item).CurrentValue = null;
                    dbcontext.Entry(entity).Property(item).IsModified = true;
                }
            }
            return dbTransaction == null ? this.dbcontext.SaveChanges() : 0;
        }

        public int Update<T>(IEnumerable<T> entities) where T : class
        {
            foreach (var entity in entities)
            {
                this.Update(entity);
            }
            return dbTransaction == null ? this.dbcontext.SaveChanges() : 0;
        }

    }
}

ORM框架學習之EF