---恢復內容開始---
1、創建倉儲模式的相關接口
2、三個文件的代碼(命名空間)
IRepository.cs代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace EnterpriseFrame.Core.Data { /// <summary> /// 這裡T是泛型,(T:class T是泛型參數。where T : class 是對T的限制,這裡的意思是T必須是引用類型,包括任何類、接口、委托或數組類型) /// </summary> /// <typeparam name="T"></typeparam> public interface IRepository<T> where T : class { /// <summary> /// Gets a table /// </summary> IQueryable<T> Table { get; } /// <summary> /// IRespository插入接口 /// </summary> /// <param name="entity"></param> /// <returns></returns> bool InsertEntity(T entity); /// <summary> /// IRespository修改接口 /// </summary> /// <param name="entity"></param> /// <returns></returns> bool UpdateEntity(T entity); /// <summary> /// IRespository刪除 /// </summary> /// <param name="entity"></param> /// <returns></returns> bool DeleteEntity(T entity); /// <summary> /// 根據id查詢 /// </summary> /// <param name="Id"></param> /// <returns></returns> T GetEntityById(object Id); /// <summary> /// 帶條件查詢 /// </summary> /// <param name="where"></param> /// <returns></returns> T Get(Expression<Func<T, bool>> where); /// <summary> /// 查詢所有 /// </summary> /// <returns></returns> IEnumerable<T> GetALLEntity(); /// <summary> /// 這裡也可以用IEnumerable類型,帶條件查詢所有 /// </summary> /// <param name="where"></param> /// <returns></returns> IQueryable<T> GetAllEntityWhere(Expression<Func<T, bool>> where); /// <summary> /// 分頁 /// </summary> /// <param name="pageIndex"></param> /// <param name="PageSize"></param> /// <returns></returns> IList<T> GetPageEntities(int pageIndex, int PageSize); /// <summary> /// 分頁帶查詢條件 /// </summary> /// <param name="pageIndex"></param> /// <param name="PageSize"></param> /// <param name="where"></param> /// <returns></returns> IList<T> GetPageEntities(int pageIndex, int PageSize, Expression<Func<T, bool>> where); } } IRepositoryEfRepository.cs代碼:
using System; using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Validation; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace EnterpriseFrame.Core.Data { public class EfRepository<T> : IRepository<T> where T : class { private readonly IDbContext _context; private IDbSet<T> _entities; public EfRepository(IDbContext context) { this._context = context; } protected virtual IDbSet<T> Entities { get { if (_entities == null) _entities = _context.Set<T>(); return _entities; } } /// <summary> /// Gets a table /// </summary> public virtual IQueryable<T> Table { get { return this.Entities; } } /// <summary> /// 插入實體 /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool InsertEntity(T entity) { bool RetStatus = false; this.Entities.Add(entity); if (Save() > 0) { RetStatus = true; } return RetStatus; } /// <summary> /// 修改實體 /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool UpdateEntity(T entity) { // throw new NotImplementedException(); bool RetStatus = false; if (entity != null && Save() > 0) { RetStatus = true; } return RetStatus; } /// <summary> /// 刪除實體 /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool DeleteEntity(T entity) { //throw new NotImplementedException(); bool RetStatus = false; if (entity != null) { this.Entities.Remove(entity); if (Save() > 0) { RetStatus = true; } } return RetStatus; } /// <summary> /// 對Set<T>根據id 的查詢的操作 /// </summary> /// <param name="Id"></param> /// <returns></returns> public T GetEntityById(object Id) { return this.Entities.Find(Id); } /// <summary> /// 這裡對Set<T>是帶條件的操作 /// </summary> /// <param name="where"></param> /// <returns></returns> public T Get(Expression<Func<T, bool>> where) { return this.Entities.Where(where).FirstOrDefault<T>(); } /// <summary> /// 查詢所有的 /// </summary> /// <returns></returns> public IEnumerable<T> GetALLEntity() { // throw new NotImplementedException(); IEnumerable<T> query = this.Entities; return query; } /// <summary> /// 查詢所有帶條件 /// </summary> /// <param name="where"></param> /// <returns></returns> public IQueryable<T> GetAllEntityWhere(Expression<Func<T, bool>> where) { IQueryable<T> query = this.Entities.Where(where); return query; } /// <summary> /// 分頁方法 /// </summary> /// <param name="pageIndex"></param> /// <param name="PageSize"></param> /// <returns></returns> public IList<T> GetPageEntities(int pageIndex, int PageSize) { IList<T> List = this.Entities.Skip(pageIndex * PageSize).Take(PageSize).ToList(); return List; } /// <summary> /// 分頁帶查詢條件 /// </summary> /// <param name="pageIndex"></param> /// <param name="PageSize"></param> /// <param name="where"></param> /// <returns></returns> public IList<T> GetPageEntities(int pageIndex, int PageSize, Expression<Func<T, bool>> where) { // throw new NotImplementedException(); IList<T> List = this.Entities.Where(where).Skip(pageIndex * PageSize).Take(PageSize).ToList(); return List; } /// <summary> /// Save 保存確認方法 /// </summary> public int Save() { return this._context.SaveChanges(); } } } EfRepositoryIDbContext.cs:
using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EnterpriseFrame.Core.Data { public interface IDbContext { /// <summary> /// Get DbSet /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <returns>DbSet</returns> IDbSet<TEntity> Set<TEntity>() where TEntity : class; /// <summary> /// Save changes /// </summary> /// <returns></returns> int SaveChanges(); /// <summary> /// Execute stores procedure and load a list of entities at the end /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <param name="commandText">Command text</param> /// <param name="parameters">Parameters</param> /// <returns>Entities</returns> IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters) where TEntity : class, new(); /// <summary> /// Creates a raw SQL query that will return elements of the given generic type. The type can be any type that has properties that match the names of the columns returned from the query, or can be a simple primitive type. The type does not have to be an entity type. The results of this query are never tracked by the context even if the type of object returned is an entity type. /// </summary> /// <typeparam name="TElement">The type of object returned by the query.</typeparam> /// <param name="sql">The SQL query string.</param> /// <param name="parameters">The parameters to apply to the SQL query string.</param> /// <returns>Result</returns> IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters); /// <summary> /// Executes the given DDL/DML command against the database. /// </summary> /// <param name="sql">The command string</param> /// <param name="doNotEnsureTransaction">false - the transaction creation is not ensured; true - the transaction creation is ensured.</param> /// <param name="timeout">Timeout value, in seconds. A null value indicates that the default value of the underlying provider will be used</param> /// <param name="parameters">The parameters to apply to the command string.</param> /// <returns>The result returned by the database after executing the command.</returns> int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters); } } IDbContext3、在EF CodeFirst中使用
using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Data.Entity.ModelConfiguration; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace EnterpriseFrame.Entity { using EnterpriseFrame.Core.Data; public partial class EnterpriseContext : DbContext, IDbContext { public EnterpriseContext(string nameOrConnectionString) : base(nameOrConnectionString) { } #region Entity public virtual DbSet<Admin> Admins { get; set; } public virtual DbSet<ArticleInfo> ArticleInfoes { get; set; } public virtual DbSet<ArticleRelation> ArticleRelations { get; set; } public virtual DbSet<ArticleType> ArticleTypes { get; set; } public virtual DbSet<FriendsLink> FriendsLinks { get; set; } public virtual DbSet<Permission> Permissions { get; set; } public virtual DbSet<Role_Permission> Role_Permission { get; set; } public virtual DbSet<Role> Roles { get; set; } public virtual DbSet<SiteALlConfig> SiteALlConfigs { get; set; } public virtual DbSet<SiteMessage> SiteMessages { get; set; } #endregion #region Utilities protected override void OnModelCreating(DbModelBuilder modelBuilder) { //dynamically load all configuration //System.Type configType = typeof(LanguageMap); //any of your configuration classes here //var typesToRegister = Assembly.GetAssembly(configType).GetTypes() var typesToRegister = Assembly.GetExecutingAssembly().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); } //...or do it manually below. For example, //modelBuilder.Configurations.Add(new LanguageMap()); modelBuilder.Entity<ArticleInfo>() .Property(e => e.ArtContent) .IsUnicode(false); modelBuilder.Entity<SiteMessage>() .Property(e => e.MsgContent) .IsUnicode(false); modelBuilder.Entity<SiteMessage>() .Property(e => e.MsgReply) .IsUnicode(false); base.OnModelCreating(modelBuilder); } #endregion #region Methods /// <summary> /// Create database script /// </summary> /// <returns>SQL to generate database</returns> public string CreateDatabaseScript() { return ((IObjectContextAdapter)this).ObjectContext.CreateDatabaseScript(); } /// <summary> /// Get DbSet /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <returns>DbSet</returns> public new IDbSet<TEntity> Set<TEntity>() where TEntity : class { return base.Set<TEntity>(); } /// <summary> /// Execute stores procedure and load a list of entities at the end /// </summary> /// <typeparam name="TEntity">Entity type</typeparam> /// <param name="commandText">Command text</param> /// <param name="parameters">Parameters</param> /// <returns>Entities</returns> public IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters) where TEntity : class, new() { //add parameters to command if (parameters != null && parameters.Length > 0) { for (int i = 0; i <= parameters.Length - 1; i++) { var p = parameters[i] as DbParameter; if (p == null) throw new Exception("Not support parameter type"); commandText += i == 0 ? " " : ", "; commandText += "@" + p.ParameterName; if (p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Output) { //output parameter commandText += " output"; } } } var result = this.Database.SqlQuery<TEntity>(commandText, parameters).ToList(); //performance hack applied as described here - http://www.nopcommerce.com/boards/t/25483/fix-very-important-speed-improvement.aspx bool acd = this.Configuration.AutoDetectChangesEnabled; try { this.Configuration.AutoDetectChangesEnabled = false; throw new System.NotImplementedException();//未實現 //for (int i = 0; i < result.Count; i++) // result[i] = AttachEntityToContext(result[i]); } finally { this.Configuration.AutoDetectChangesEnabled = acd; } return result; } /// <summary> /// Creates a raw SQL query that will return elements of the given generic type. The type can be any type that has properties that match the names of the columns returned from the query, or can be a simple primitive type. The type does not have to be an entity type. The results of this query are never tracked by the context even if the type of object returned is an entity type. /// </summary> /// <typeparam name="TElement">The type of object returned by the query.</typeparam> /// <param name="sql">The SQL query string.</param> /// <param name="parameters">The parameters to apply to the SQL query string.</param> /// <returns>Result</returns> public IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters) { return this.Database.SqlQuery<TElement>(sql, parameters); } /// <summary> /// Executes the given DDL/DML command against the database. /// </summary> /// <param name="sql">The command string</param> /// <param name="doNotEnsureTransaction">false - the transaction creation is not ensured; true - the transaction creation is ensured.</param> /// <param name="timeout">Timeout value, in seconds. A null value indicates that the default value of the underlying provider will be used</param> /// <param name="parameters">The parameters to apply to the command string.</param> /// <returns>The result returned by the database after executing the command.</returns> public int ExecuteSqlCommand(string sql, bool doNotEnsureTransaction = false, int? timeout = null, params object[] parameters) { int? previousTimeout = null; if (timeout.HasValue) { //store previous timeout previousTimeout = ((IObjectContextAdapter)this).ObjectContext.CommandTimeout; ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = timeout; } var transactionalBehavior = doNotEnsureTransaction ? TransactionalBehavior.DoNotEnsureTransaction : TransactionalBehavior.EnsureTransaction; var result = this.Database.ExecuteSqlCommand(transactionalBehavior, sql, parameters); if (timeout.HasValue) { //Set previous timeout back ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = previousTimeout; } //return result return result; } #endregion } } EnterpriseContextgit地址:https://github.com/yimogit/EnterpriseFrame
文筆有限,就直接貼代碼了。記錄下自己開發需要到的干貨。希望不會誤導路過的各位,文中若有誤,還望路過的道友指出。