ORM框架學習之EF
阿新 • • 發佈:2018-10-03
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() == " "||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