本文共 10416 字,大约阅读时间需要 34 分钟。
之前我们系统学习了EntityFramework,个人觉得有些东西不能学了就算完了,必须要学以致用,在Web API上也少不了增(C)、删(D)、改(U)、查(R)。鉴于此,我们通过EF来实现Web API上的增删改查。
我们建立一个Core(核心类库),里面存放有关EF的完成封装。
public class BaseEntity{ public T Id { get; set; } }
public interface IRepositorywhere TEntity : class { /// /// 获得数据列表 /// ///IQueryable GetList(); /// /// 通过id获得实体 /// /// ///TEntity GetById(object id); /// /// 添加实体 /// /// int Insert(TEntity entity); ////// 添加实体集合 /// /// int Insert(IEnumerableentities); /// /// 删除实体 /// /// int Delete(TEntity entity); ////// 根据条件删除实体 /// /// int DeleteByRequirement(Expression> func); /// /// 更新实体 /// /// int Update(TEntity entity); ////// 更新实体集合 /// /// int Update(IEnumerableentities); }
public class RepositoryService: IRepository where TEntity : class { private IDbContext Context; private bool IsNoTracking; /// /// 获取实体集合 /// private IDbSetEntities { get { return this.Context.Set (); } } private DbEntityEntry Entry(TEntity entity) { return this.Context.Entry (entity); } public RepositoryService(IDbContext context, bool isNoTracking) { this.Context = context; this.IsNoTracking = isNoTracking; } /// /// 获取所有数据 /// ///public IQueryable GetList() { if (!IsNoTracking) return this.Entities.AsQueryable(); else return this.Entities.AsNoTracking().AsQueryable(); } /// /// 通过id获取实体 /// /// ///public TEntity GetById(object id) { return Entities.Find(id); } /// /// 添加实体 /// /// public int Insert(TEntity entity) { Entities.Add(entity); return this.Context.SaveChanges(); } public int Insert(IEnumerableentities) { if (entities == null) throw new ArgumentNullException("entities"); foreach (var entity in entities) { Entities.Add(entity); } return this.Context.SaveChanges(); } /// /// 删除实体 /// /// public int Delete(TEntity entity) { if (!IsNoTracking) this.Entities.Remove(entity); else this.Entities.Attach(entity); this.Entities.Remove(entity); return this.Context.SaveChanges(); } public int DeleteByRequirement(Expression> func) { var list = GetList().Where(func).ToList(); list.ForEach(e => { if (!IsNoTracking) this.Entities.Remove(e); else this.Entities.Attach(e); this.Entities.Remove(e); }); return this.Context.SaveChanges(); } /// /// 更新实体 /// /// public int Update(TEntity entity) { if (!IsNoTracking) return this.Context.SaveChanges(); else this.Context.Entry(entity).State = EntityState.Modified; return this.Context.SaveChanges(); } public int Update(IEnumerableentities) { if (entities == null) throw new ArgumentNullException("enetities"); if (!IsNoTracking) return this.Context.SaveChanges(); else foreach (var t in entities) { this.Context.Entry(t).State = EntityState.Modified; } return this.Context.SaveChanges(); } /// /// 释放资源 /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { if (Context != null) { this.Context.Dispose(); this.Context = null; } } } }
public interface IDbContext { ////// 获得实体集合 /// ////// IDbSet Set () where TEntity : class; /// /// 执行存储过程 /// ////// /// /// IList ExecuteStoredProcedureList (string commandText, params object[] parameters) where TEntity : class; /// /// 执行SQL语句查询 /// ////// /// /// IEnumerable SqlQuery (string sql, params object[] parameters); DbEntityEntry Entry (TEntity entity) where TEntity : class; /// /// 保存数据 /// ///int SaveChanges(); /// /// 变更追踪代码 /// bool ProxyCreationEnabled { get; set; } ////// DetectChanges方法自动调用 /// bool AutoDetectChangesEnabled { get; set; } ////// 调用Dispose方法 /// void Dispose(); }
public class EFDbContext : DbContext, IDbContext { public EFDbContext(string connectionString) : base(connectionString) { } static EFDbContext() { Database.SetInitializer(new DropCreateDatabaseIfModelChanges ()); } /// /// 一次性加载所有映射 /// /// protected override void OnModelCreating(DbModelBuilder modelBuilder) { 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); } base.OnModelCreating(modelBuilder); } ////// 获得实体集合 /// ////// public new IDbSet Set () where TEntity : class { return base.Set (); } /// /// 实体状态 /// ////// /// public new DbEntityEntry Entry (TEntity entity) where TEntity : class { return base.Entry (entity); } /// /// 执行存储过程 /// ////// /// /// public IList ExecuteStoredProcedureList (string commandText, params object[] parameters) where TEntity : class { 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) { commandText += " output"; } } } var result = this.Database.SqlQuery (commandText, parameters).ToList(); bool acd = this.Configuration.AutoDetectChangesEnabled; try { this.Configuration.AutoDetectChangesEnabled = false; for (int i = 0; i < result.Count; i++) result[i] = this.Set ().Attach(result[i]); } finally { this.Configuration.AutoDetectChangesEnabled = acd; } return result; } /// /// SQL语句查询 /// ////// /// /// public IEnumerable SqlQuery (string sql, params object[] parameters) { return this.Database.SqlQuery (sql, parameters); } /// /// 当查询或者获取值时是否启动创建代理 /// public virtual bool ProxyCreationEnabled { get { return this.Configuration.ProxyCreationEnabled; } set { this.Configuration.ProxyCreationEnabled = value; } } ////// 当查询或者获取值时指定是否开启自动调用DetectChanges方法 /// public virtual bool AutoDetectChangesEnabled { get { return this.Configuration.AutoDetectChangesEnabled; } set { this.Configuration.AutoDetectChangesEnabled = value; } } }
以上就是对利用EntityFramework来实现基本操作的完整封装。接下来就是相关类以及映射(场景:一个Student对应一个Flower,而一个Flower对应多个Student)
public class Student : BaseEntity { public string Name { get; set; } public int FlowerId { get; set; } public virtual Flower Flower { get; set; } }
public class Flower : BaseEntity { public string Remark { get; set; } public virtual ICollectionStudents { get; set; } }
public class StudentMap:EntityTypeConfiguration{ public StudentMap() { ToTable("Student"); HasKey(p => p.Id); Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); HasRequired(p => p.Flower).WithMany(p => p.Students).HasForeignKey(p => p.FlowerId); } } public class FlowerMap:EntityTypeConfiguration { public FlowerMap() { ToTable("Flower"); HasKey(p => p.Id); Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); } }
接下来就是Web API控制器中执行增、删等操作,我们创建一个StudentController控制器,然后首先创建仓储服务。(执行Action方法,依据默认约定,未添加特性)
public IRepository_repository; public EFDbContext _ctx; public StudentController() { _ctx = new EFDbContext("DBByConnectionString"); _repository = new RepositoryService (_ctx, true); //关闭局部变更追踪 }
public IEnumerableGetAllStudent() { return _repository.GetList().Select(d => new Student { Name = d.Name, Flower = d.Flower, Id = d.Id }).ToList(); }
当执行此查询操作时却出错了,真遗憾:
上述修改如下即可:
return _repository.GetList().ToList().Select(d => new Student { Name = d.Name, Flower = d.Flower, Id = d.Id }).ToList();
在此感谢园友()给出的解决方案,在GetList之后利用 Linq 进行Select,最后进行ToList即可!!!
这节主要介绍了利用仓储模式完整封装EF来进行Web API基本操作,基本操作中关于返回状态码等信息,无非就是以下几个对象
HttpResponseException 返回异常HttpResponseMessage 返回信息(诸如状态码等)HttpStatusCode 状态码枚举(如页面未找到等)
本文转自Jeffcky博客园博客,原文链接:http://www.cnblogs.com/CreateMyself/p/4820121.html,如需转载请自行联系原作者