日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Web APi之EntityFramework【CRUD】(三)

發(fā)布時間:2024/4/17 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Web APi之EntityFramework【CRUD】(三) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

之前我們系統(tǒng)學習了EntityFramework,個人覺得有些東西不能學了就算完了,必須要學以致用,在Web API上也少不了增(C)、刪(D)、改(U)、查(R)。鑒于此,我們通過EF來實現(xiàn)Web API上的增刪改查。

?

之前對于EF的基本操作都是很零散的,我們應該對于CRUD都是通過完整封裝來實現(xiàn),并且也顯得比較專業(yè),接下來首先對EF利用Responsitory倉儲模式進行完整封裝。

?

EntityFramework完整封裝

我們建立一個Core(核心類庫),里面存放有關EF的完成封裝。

第一步

建立所有實體的基類,將實體的公共屬性放入其中,取為BaseEntity

public class BaseEntity<T>{public T Id { get; set; }}

第二步

建立倉儲接口IRepository,包括基本的增、刪、改、查等方法

public interface IRepository<TEntity> where TEntity : class{/// <summary>/// 獲得數(shù)據(jù)列表/// </summary>/// <returns></returns>IQueryable<TEntity> GetList();/// <summary>/// 通過id獲得實體/// </summary>/// <param name="id"></param>/// <returns></returns>TEntity GetById(object id);/// <summary>/// 添加實體/// </summary>/// <param name="entity"></param>int Insert(TEntity entity);/// <summary>/// 添加實體集合/// </summary>/// <param name="entities"></param>int Insert(IEnumerable<TEntity> entities);/// <summary>/// 刪除實體/// </summary>/// <param name="entity"></param>int Delete(TEntity entity);/// <summary>/// 根據(jù)條件刪除實體/// </summary>/// <param name="entities"></param>int DeleteByRequirement(Expression<Func<TEntity, bool>> func);/// <summary>/// 更新實體/// </summary>/// <param name="entity"></param>int Update(TEntity entity);/// <summary>/// 更新實體集合/// </summary>/// <param name="entities"></param>int Update(IEnumerable<TEntity> entities);}

?

?第三步

利用倉儲服務RepositoryService實現(xiàn)上述倉儲接口IRepository

public class RepositoryService<TEntity> : IRepository<TEntity> where TEntity : class{private IDbContext Context;private bool IsNoTracking;/// <summary>/// 獲取實體集合/// </summary>private IDbSet<TEntity> Entities{get{return this.Context.Set<TEntity>();}}private DbEntityEntry Entry(TEntity entity){return this.Context.Entry<TEntity>(entity);}public RepositoryService(IDbContext context, bool isNoTracking){this.Context = context;this.IsNoTracking = isNoTracking;}/// <summary>/// 獲取所有數(shù)據(jù)/// </summary>/// <returns></returns>public IQueryable<TEntity> GetList(){if (!IsNoTracking)return this.Entities.AsQueryable();elsereturn this.Entities.AsNoTracking().AsQueryable();}/// <summary>/// 通過id獲取實體/// </summary>/// <param name="id"></param>/// <returns></returns>public TEntity GetById(object id){return Entities.Find(id);}/// <summary>/// 添加實體/// </summary>/// <param name="entity"></param>public int Insert(TEntity entity){Entities.Add(entity);return this.Context.SaveChanges();}public int Insert(IEnumerable<TEntity> entities){if (entities == null)throw new ArgumentNullException("entities");foreach (var entity in entities){Entities.Add(entity);}return this.Context.SaveChanges();}/// <summary>/// 刪除實體/// </summary>/// <param name="entity"></param>public int Delete(TEntity entity){if (!IsNoTracking)this.Entities.Remove(entity);elsethis.Entities.Attach(entity);this.Entities.Remove(entity);return this.Context.SaveChanges();}public int DeleteByRequirement(Expression<Func<TEntity, bool>> func){var list = GetList().Where(func).ToList();list.ForEach(e =>{if (!IsNoTracking)this.Entities.Remove(e);elsethis.Entities.Attach(e);this.Entities.Remove(e);});return this.Context.SaveChanges();}/// <summary>/// 更新實體/// </summary>/// <param name="entity"></param>public int Update(TEntity entity){if (!IsNoTracking)return this.Context.SaveChanges();elsethis.Context.Entry(entity).State = EntityState.Modified;return this.Context.SaveChanges();}public int Update(IEnumerable<TEntity> entities){if (entities == null)throw new ArgumentNullException("enetities");if (!IsNoTracking)return this.Context.SaveChanges();elseforeach (var t in entities){this.Context.Entry(t).State = EntityState.Modified;}return this.Context.SaveChanges();}/// <summary>/// 釋放資源/// </summary>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;}}}}

第四步

用接口IDbContext封裝EF上下文DbContext中的公共方法

public interface IDbContext{/// <summary>/// 獲得實體集合/// </summary>/// <typeparam name="TEntity"></typeparam>/// <returns></returns>IDbSet<TEntity> Set<TEntity>() where TEntity : class;/// <summary>/// 執(zhí)行存儲過程/// </summary>/// <typeparam name="TEntity"></typeparam>/// <param name="commandText"></param>/// <param name="parameters"></param>/// <returns></returns>IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters)where TEntity : class;/// <summary>/// 執(zhí)行SQL語句查詢/// </summary>/// <typeparam name="TElement"></typeparam>/// <param name="sql"></param>/// <param name="parameters"></param>/// <returns></returns>IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters);DbEntityEntry Entry<TEntity>(TEntity entity) where TEntity : class;/// <summary>/// 保存數(shù)據(jù)/// </summary>/// <returns></returns>int SaveChanges();/// <summary>/// 變更追蹤代碼/// </summary>bool ProxyCreationEnabled { get; set; }/// <summary>/// DetectChanges方法自動調(diào)用/// </summary>bool AutoDetectChangesEnabled { get; set; }/// <summary>/// 調(diào)用Dispose方法/// </summary>void Dispose();}

第五步

實現(xiàn)EF上下文中的數(shù)據(jù)庫連接、模型初始化以及映射等(也可以手動關閉全局變更追蹤相對比較靈活)

public class EFDbContext : DbContext, IDbContext{public EFDbContext(string connectionString): base(connectionString){ }static EFDbContext(){Database.SetInitializer<EFDbContext>(new DropCreateDatabaseIfModelChanges<EFDbContext>());}/// <summary>/// 一次性加載所有映射/// </summary>/// <param name="modelBuilder"></param>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);}/// <summary>/// 獲得實體集合/// </summary>/// <typeparam name="TEntity"></typeparam>/// <returns></returns>public new IDbSet<TEntity> Set<TEntity>() where TEntity : class{return base.Set<TEntity>();}/// <summary>/// 實體狀態(tài)/// </summary>/// <typeparam name="TEntity"></typeparam>/// <param name="entity"></param>/// <returns></returns>public new DbEntityEntry Entry<TEntity>(TEntity entity) where TEntity : class{return base.Entry<TEntity>(entity);}/// <summary>/// 執(zhí)行存儲過程/// </summary>/// <typeparam name="TEntity"></typeparam>/// <param name="commandText"></param>/// <param name="parameters"></param>/// <returns></returns>public IList<TEntity> ExecuteStoredProcedureList<TEntity>(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<TEntity>(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<TEntity>().Attach(result[i]);}finally{this.Configuration.AutoDetectChangesEnabled = acd;}return result;}/// <summary>/// SQL語句查詢/// </summary>/// <typeparam name="TElement"></typeparam>/// <param name="sql"></param>/// <param name="parameters"></param>/// <returns></returns>public IEnumerable<TElement> SqlQuery<TElement>(string sql, params object[] parameters){return this.Database.SqlQuery<TElement>(sql, parameters);}/// <summary>/// 當查詢或者獲取值時是否啟動創(chuàng)建代理/// </summary>public virtual bool ProxyCreationEnabled{get{return this.Configuration.ProxyCreationEnabled;}set{this.Configuration.ProxyCreationEnabled = value;}}/// <summary>/// 當查詢或者獲取值時指定是否開啟自動調(diào)用DetectChanges方法/// </summary>public virtual bool AutoDetectChangesEnabled{get{return this.Configuration.AutoDetectChangesEnabled;}set{this.Configuration.AutoDetectChangesEnabled = value;}}}

?以上就是對利用EntityFramework來實現(xiàn)基本操作的完整封裝。接下來就是相關類以及映射(場景:一個Student對應一個Flower,而一個Flower對應多個Student)

Student

public class Student : BaseEntity<int>{public string Name { get; set; }public int FlowerId { get; set; }public virtual Flower Flower { get; set; }}

Flower

public class Flower : BaseEntity<int>{public string Remark { get; set; }public virtual ICollection<Student> Students { get; set; }}

相關映射

public class StudentMap:EntityTypeConfiguration<Student>{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<Flower>{public FlowerMap(){ToTable("Flower");HasKey(p => p.Id);Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);}}

CRUD?

接下來就是Web API控制器中執(zhí)行增、刪等操作,我們創(chuàng)建一個StudentController控制器,然后首先創(chuàng)建倉儲服務。(執(zhí)行Action方法,依據(jù)默認約定,未添加特性)

public IRepository<Student> _repository;public EFDbContext _ctx;public StudentController(){_ctx = new EFDbContext("DBByConnectionString");_repository = new RepositoryService<Student>(_ctx, true); //關閉局部變更追蹤}

執(zhí)行R操作(即默認請求到HttpGet方法)

public IEnumerable<Student> GetAllStudent(){return _repository.GetList().Select(d => new Student { Name = d.Name, Flower = d.Flower, Id = d.Id }).ToList();}

當執(zhí)行此查詢操作時卻出錯了,真遺憾:

上述修改如下即可:

return _repository.GetList().ToList().Select(d => new Student { Name = d.Name, Flower = d.Flower, Id = d.Id }).ToList();

不知道還有沒有更好的解決方案,用ToList直接將所有數(shù)據(jù)進行加載到內(nèi)存中,在性能上消耗比較大。(期待你的解決方案)

特此記錄

在此感謝園友(_天光云影)給出的解決方案,在GetList之后利用?Linq?進行Select,最后進行ToList即可!!!

執(zhí)行CUD等操作

public Student GetStudentById(int id){var student = _repository.GetById(id);if (student == null)throw new HttpResponseException(HttpStatusCode.NotFound);elsereturn student;}//添加操作(HttpPost)public HttpResponseMessage PostStudent(Student stu){var insertStudent = _repository.Insert(stu);var response = Request.CreateResponse<Student>(HttpStatusCode.Created, stu);string uri = Url.Link("DefaultApi", new { id = stu.Id });response.Headers.Location = new Uri(uri);return response;}//更新操作(HttpPut)public void PutStudent(int id, Student stu){stu.Id = id;if (_repository.Update(stu) <= 0){throw new HttpResponseException(HttpStatusCode.NotFound);}}//刪除操作(HttpDelete)public void DeleteStudent(int id){Student stu = _repository.GetById(id);if (stu == null){throw new HttpResponseException(HttpStatusCode.NotFound);}_repository.Delete(stu);} View Code

?總結(jié)

這節(jié)主要介紹了利用倉儲模式完整封裝EF來進行Web API基本操作,基本操作中關于返回狀態(tài)碼等信息,無非就是以下幾個對象

HttpResponseException 返回異常HttpResponseMessage 返回信息(諸如狀態(tài)碼等)HttpStatusCode 狀態(tài)碼枚舉(如頁面未找到等)

?源代碼下載

【W(wǎng)ebAPI之EntityFramework】

?

轉(zhuǎn)載于:https://www.cnblogs.com/CreateMyself/p/4820121.html

總結(jié)

以上是生活随笔為你收集整理的Web APi之EntityFramework【CRUD】(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。