ABP+NetCore+Vue.js实现增删改查
ABP我就不多介绍了,不知道的可以自己百度
本篇开发工具VS2017,数据库SQL SERVER2012,系统Win7
1、去ABP官网下载对应的模板,下载地址:https://aspnetboilerplate.com/Templates
2、用VS2017打开解压后的项目,找到src下web项目下appsettings.json文件。打开后修改数据库连接字符串
图我就不截了,涉及个人隐私
3、在Core项目下添加二个文件夹,一个Entities文件夹存放所有的实体,一个IRepositories文件夹存放所有的仓储接口
IRepositories文件夹里面的仓储接口主要是自己定义除IRepository<TEntity, TPrimaryKey>没有定义的接口,本文的增删改查IRepository<TEntity, TPrimaryKey>都已经定义了,
所以IRepositories文件夹里面东西对本文作用不大,但是作为一名高度强迫症患者,还是添加此文件夹以备不时之需
附IRepository<TEntity, TPrimaryKey>定义的接口
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Linq.Expressions; 5 using System.Threading.Tasks; 6 using Abp.Dependency; 7 using Abp.Domain.Entities; 8 9 namespace Abp.Domain.Repositories 10 { 11 // 12 // 摘要: 13 // This interface is implemented by all repositories to ensure implementation of 14 // fixed methods. 15 // 16 // 类型参数: 17 // TEntity: 18 // Main Entity type this repository works on 19 // 20 // TPrimaryKey: 21 // Primary key type of the entity 22 public interface IRepository<TEntity, TPrimaryKey> : IRepository, ITransientDependency where TEntity : class, IEntity<TPrimaryKey> 23 { 24 // 25 // 摘要: 26 // Gets count of all entities in this repository. 27 // 28 // 返回结果: 29 // Count of entities 30 int Count(); 31 // 32 // 摘要: 33 // Gets count of all entities in this repository based on given predicate. 34 // 35 // 参数: 36 // predicate: 37 // A method to filter count 38 // 39 // 返回结果: 40 // Count of entities 41 int Count(Expression<Func<TEntity, bool>> predicate); 42 // 43 // 摘要: 44 // Gets count of all entities in this repository based on given predicate. 45 // 46 // 参数: 47 // predicate: 48 // A method to filter count 49 // 50 // 返回结果: 51 // Count of entities 52 Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate); 53 // 54 // 摘要: 55 // Gets count of all entities in this repository. 56 // 57 // 返回结果: 58 // Count of entities 59 Task<int> CountAsync(); 60 // 61 // 摘要: 62 // Deletes an entity. 63 // 64 // 参数: 65 // entity: 66 // Entity to be deleted 67 void Delete(TEntity entity); 68 // 69 // 摘要: 70 // Deletes an entity by primary key. 71 // 72 // 参数: 73 // id: 74 // Primary key of the entity 75 void Delete(TPrimaryKey id); 76 // 77 // 摘要: 78 // Deletes many entities by function. Notice that: All entities fits to given predicate 79 // are retrieved and deleted. This may cause major performance problems if there 80 // are too many entities with given predicate. 81 // 82 // 参数: 83 // predicate: 84 // A condition to filter entities 85 void Delete(Expression<Func<TEntity, bool>> predicate); 86 // 87 // 摘要: 88 // Deletes an entity by primary key. 89 // 90 // 参数: 91 // id: 92 // Primary key of the entity 93 Task DeleteAsync(TPrimaryKey id); 94 // 95 // 摘要: 96 // Deletes many entities by function. Notice that: All entities fits to given predicate 97 // are retrieved and deleted. This may cause major performance problems if there 98 // are too many entities with given predicate. 99 // 100 // 参数: 101 // predicate: 102 // A condition to filter entities 103 Task DeleteAsync(Expression<Func<TEntity, bool>> predicate); 104 // 105 // 摘要: 106 // Deletes an entity. 107 // 108 // 参数: 109 // entity: 110 // Entity to be deleted 111 Task DeleteAsync(TEntity entity); 112 // 113 // 摘要: 114 // Gets an entity with given given predicate or null if not found. 115 // 116 // 参数: 117 // predicate: 118 // Predicate to filter entities 119 TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate); 120 // 121 // 摘要: 122 // Gets an entity with given primary key or null if not found. 123 // 124 // 参数: 125 // id: 126 // Primary key of the entity to get 127 // 128 // 返回结果: 129 // Entity or null 130 TEntity FirstOrDefault(TPrimaryKey id); 131 // 132 // 摘要: 133 // Gets an entity with given given predicate or null if not found. 134 // 135 // 参数: 136 // predicate: 137 // Predicate to filter entities 138 Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate); 139 // 140 // 摘要: 141 // Gets an entity with given primary key or null if not found. 142 // 143 // 参数: 144 // id: 145 // Primary key of the entity to get 146 // 147 // 返回结果: 148 // Entity or null 149 Task<TEntity> FirstOrDefaultAsync(TPrimaryKey id); 150 // 151 // 摘要: 152 // Gets an entity with given primary key. 153 // 154 // 参数: 155 // id: 156 // Primary key of the entity to get 157 // 158 // 返回结果: 159 // Entity 160 TEntity Get(TPrimaryKey id); 161 // 162 // 摘要: 163 // Used to get a IQueryable that is used to retrieve entities from entire table. 164 // 165 // 返回结果: 166 // IQueryable to be used to select entities from database 167 IQueryable<TEntity> GetAll(); 168 // 169 // 摘要: 170 // Used to get a IQueryable that is used to retrieve entities from entire table. 171 // One or more 172 // 173 // 参数: 174 // propertySelectors: 175 // A list of include expressions. 176 // 177 // 返回结果: 178 // IQueryable to be used to select entities from database 179 IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] propertySelectors); 180 // 181 // 摘要: 182 // Used to get all entities based on given predicate. 183 // 184 // 参数: 185 // predicate: 186 // A condition to filter entities 187 // 188 // 返回结果: 189 // List of all entities 190 List<TEntity> GetAllList(Expression<Func<TEntity, bool>> predicate); 191 // 192 // 摘要: 193 // Used to get all entities. 194 // 195 // 返回结果: 196 // List of all entities 197 List<TEntity> GetAllList(); 198 // 199 // 摘要: 200 // Used to get all entities based on given predicate. 201 // 202 // 参数: 203 // predicate: 204 // A condition to filter entities 205 // 206 // 返回结果: 207 // List of all entities 208 Task<List<TEntity>> GetAllListAsync(Expression<Func<TEntity, bool>> predicate); 209 // 210 // 摘要: 211 // Used to get all entities. 212 // 213 // 返回结果: 214 // List of all entities 215 Task<List<TEntity>> GetAllListAsync(); 216 // 217 // 摘要: 218 // Gets an entity with given primary key. 219 // 220 // 参数: 221 // id: 222 // Primary key of the entity to get 223 // 224 // 返回结果: 225 // Entity 226 Task<TEntity> GetAsync(TPrimaryKey id); 227 // 228 // 摘要: 229 // Inserts a new entity. 230 // 231 // 参数: 232 // entity: 233 // Inserted entity 234 TEntity Insert(TEntity entity); 235 // 236 // 摘要: 237 // Inserts a new entity and gets it's Id. It may require to save current unit of 238 // work to be able to retrieve id. 239 // 240 // 参数: 241 // entity: 242 // Entity 243 // 244 // 返回结果: 245 // Id of the entity 246 TPrimaryKey InsertAndGetId(TEntity entity); 247 // 248 // 摘要: 249 // Inserts a new entity and gets it's Id. It may require to save current unit of 250 // work to be able to retrieve id. 251 // 252 // 参数: 253 // entity: 254 // Entity 255 // 256 // 返回结果: 257 // Id of the entity 258 Task<TPrimaryKey> InsertAndGetIdAsync(TEntity entity); 259 // 260 // 摘要: 261 // Inserts a new entity. 262 // 263 // 参数: 264 // entity: 265 // Inserted entity 266 Task<TEntity> InsertAsync(TEntity entity); 267 // 268 // 摘要: 269 // Inserts or updates given entity depending on Id's value. 270 // 271 // 参数: 272 // entity: 273 // Entity 274 TEntity InsertOrUpdate(TEntity entity); 275 // 276 // 摘要: 277 // Inserts or updates given entity depending on Id's value. Also returns Id of the 278 // entity. It may require to save current unit of work to be able to retrieve id. 279 // 280 // 参数: 281 // entity: 282 // Entity 283 // 284 // 返回结果: 285 // Id of the entity 286 TPrimaryKey InsertOrUpdateAndGetId(TEntity entity); 287 // 288 // 摘要: 289 // Inserts or updates given entity depending on Id's value. Also returns Id of the 290 // entity. It may require to save current unit of work to be able to retrieve id. 291 // 292 // 参数: 293 // entity: 294 // Entity 295 // 296 // 返回结果: 297 // Id of the entity 298 Task<TPrimaryKey> InsertOrUpdateAndGetIdAsync(TEntity entity); 299 // 300 // 摘要: 301 // Inserts or updates given entity depending on Id's value. 302 // 303 // 参数: 304 // entity: 305 // Entity 306 Task<TEntity> InsertOrUpdateAsync(TEntity entity); 307 // 308 // 摘要: 309 // Creates an entity with given primary key without database access. 310 // 311 // 参数: 312 // id: 313 // Primary key of the entity to load 314 // 315 // 返回结果: 316 // Entity 317 TEntity Load(TPrimaryKey id); 318 // 319 // 摘要: 320 // Gets count of all entities in this repository based on given predicate (use this 321 // overload if expected return value is greather than System.Int32.MaxValue). 322 // 323 // 参数: 324 // predicate: 325 // A method to filter count 326 // 327 // 返回结果: 328 // Count of entities 329 long LongCount(Expression<Func<TEntity, bool>> predicate); 330 // 331 // 摘要: 332 // Gets count of all entities in this repository (use if expected return value is 333 // greather than System.Int32.MaxValue. 334 // 335 // 返回结果: 336 // Count of entities 337 long LongCount(); 338 // 339 // 摘要: 340 // Gets count of all entities in this repository (use if expected return value is 341 // greather than System.Int32.MaxValue. 342 // 343 // 返回结果: 344 // Count of entities 345 Task<long> LongCountAsync(); 346 // 347 // 摘要: 348 // Gets count of all entities in this repository based on given predicate (use this 349 // overload if expected return value is greather than System.Int32.MaxValue). 350 // 351 // 参数: 352 // predicate: 353 // A method to filter count 354 // 355 // 返回结果: 356 // Count of entities 357 Task<long> LongCountAsync(Expression<Func<TEntity, bool>> predicate); 358 // 359 // 摘要: 360 // Used to run a query over entire entities. Abp.Domain.Uow.UnitOfWorkAttribute 361 // attribute is not always necessary (as opposite to Abp.Domain.Repositories.IRepository`2.GetAll) 362 // if queryMethod finishes IQueryable with ToList, FirstOrDefault etc.. 363 // 364 // 参数: 365 // queryMethod: 366 // This method is used to query over entities 367 // 368 // 类型参数: 369 // T: 370 // Type of return value of this method 371 // 372 // 返回结果: 373 // Query result 374 T Query<T>(Func<IQueryable<TEntity>, T> queryMethod); 375 // 376 // 摘要: 377 // Gets exactly one entity with given predicate. Throws exception if no entity or 378 // more than one entity. 379 // 380 // 参数: 381 // predicate: 382 // Entity 383 TEntity Single(Expression<Func<TEntity, bool>> predicate); 384 // 385 // 摘要: 386 // Gets exactly one entity with given predicate. Throws exception if no entity or 387 // more than one entity. 388 // 389 // 参数: 390 // predicate: 391 // Entity 392 Task<TEntity> SingleAsync(Expression<Func<TEntity, bool>> predicate); 393 // 394 // 摘要: 395 // Updates an existing entity. 396 // 397 // 参数: 398 // entity: 399 // Entity 400 TEntity Update(TEntity entity); 401 // 402 // 摘要: 403 // Updates an existing entity. 404 // 405 // 参数: 406 // id: 407 // Id of the entity 408 // 409 // updateAction: 410 // Action that can be used to change values of the entity 411 // 412 // 返回结果: 413 // Updated entity 414 TEntity Update(TPrimaryKey id, Action<TEntity> updateAction); 415 // 416 // 摘要: 417 // Updates an existing entity. 418 // 419 // 参数: 420 // id: 421 // Id of the entity 422 // 423 // updateAction: 424 // Action that can be used to change values of the entity 425 // 426 // 返回结果: 427 // Updated entity 428 Task<TEntity> UpdateAsync(TPrimaryKey id, Func<TEntity, Task> updateAction); 429 // 430 // 摘要: 431 // Updates an existing entity. 432 // 433 // 参数: 434 // entity: 435 // Entity 436 Task<TEntity> UpdateAsync(TEntity entity); 437 } 438 }
4、自定义实体类User和仓储接口IUserRepository
1 using Abp.Domain.Entities; 2 using System; 3 using System.Collections.Generic; 4 using System.ComponentModel.DataAnnotations; 5 using System.Text; 6 7 namespace Ocean.Entities 8 { 9 public class User : Entity 10 { 11 /// <summary> 12 /// 用户名 13 /// </summary> 14 [MaxLength(500)] 15 public virtual string UserName { get; set; } 16 17 /// <summary> 18 /// 真实姓名 19 /// </summary> 20 [MaxLength(500)] 21 public virtual string RealName { get; set; } 22 23 /// <summary> 24 /// 邮箱 25 /// </summary> 26 [MaxLength(50)] 27 public virtual string Email { get; set; } 28 29 /// <summary> 30 /// 添加时间 31 /// </summary> 32 public virtual DateTime CreationTime { get; set; } = DateTime.Now; 33 34 /// <summary> 35 /// 用户状态 36 /// </summary> 37 public virtual int Status { get; set; } = 0; 38 } 39 }
1 using Abp.Domain.Repositories; 2 using System; 3 using System.Collections.Generic; 4 using System.Text; 5 6 namespace Ocean.IRepositories 7 { 8 public interface IUserRepository : IRepository 9 { 10 //自定义除增删改查基本操作之外的其余方法接口 11 } 12 }
5、去EntityFrameworkCore下EntityFrameworkCore文件夹里添加个Repositories文件夹,里面主要存放实现自定义仓储接口的方法
1 using Ocean.IRepositories; 2 using System; 3 using System.Collections.Generic; 4 using System.Text; 5 6 namespace Ocean.EntityFrameworkCore.Repositories 7 { 8 public class UserRepository : IUserRepository 9 { 10 // 11 } 12 }
6、EntityFrameworkCore下找到 DbContext文件打开,添加对应的DbSet
1 using Abp.EntityFrameworkCore; 2 using Microsoft.EntityFrameworkCore; 3 using Ocean.Entities; 4 5 namespace Ocean.EntityFrameworkCore 6 { 7 public class OceanDbContext : AbpDbContext 8 { 9 //Add DbSet properties for your entities... 10 public virtual DbSet<User> User { get; set; } 11 12 public OceanDbContext(DbContextOptions<OceanDbContext> options) 13 : base(options) 14 { 15 // 16 } 17 } 18 }
7、打开工具--Nuget包管理器--程序包管理器控制台,默认项目选择EntityFrameworkCore并设定Web为解决方案的启动项目
执行命令 Add-Migration InitialCreate
成功后看Migrations文件夹里面生成的文件
然后执行命令 Update-Database
成功后就可以看到在数据库中生成的数据库和表了
8、来到Application项目中,添加一个定义的实体类文件夹,并在文件夹中添加一个IAppservice接口和一个AppService类
1 using Abp.Application.Services; 2 using System; 3 using System.Collections.Generic; 4 using System.Text; 5 6 namespace Ocean.User 7 { 8 public interface IUserAppService : IApplicationService 9 { 10 List<Entities.User> GetUsers(); 11 12 void UpdateUser(Entities.User entity); 13 14 void CreateUser(Entities.User entity); 15 16 void DeleteUser(int Id); 17 } 18 }
1 using Abp.Domain.Repositories; 2 using Ocean.Entities; 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 8 namespace Ocean.User 9 { 10 public class UserAppService : OceanAppServiceBase, IUserAppService 11 { 12 private readonly IRepository<Entities.User> _UserRepository; 13 public UserAppService(IRepository<Entities.User> userRepository) 14 { 15 _UserRepository = userRepository; 16 } 17 18 public void CreateUser(Entities.User entity) 19 { 20 Logger.Info($"Created a User for entity at:{DateTime.Now}"); 21 try 22 { 23 _UserRepository.Insert(entity); 24 } 25 catch (Exception ex) 26 { 27 Logger.Error(ex.ToString()); 28 } 29 } 30 31 public void DeleteUser(int Id) 32 { 33 Logger.Info($"Deleted a User for Id at:{DateTime.Now}"); 34 try 35 { 36 _UserRepository.Delete(Id); 37 } 38 catch (Exception ex) 39 { 40 Logger.Error(ex.ToString()); 41 } 42 } 43 44 public List<Entities.User> GetUsers() 45 { 46 List<Entities.User> list = new List<Entities.User>(); 47 Logger.Info($"Get Users List at:{DateTime.Now}"); 48 try 49 { 50 list = _UserRepository.GetAll().ToList(); 51 } 52 catch (Exception ex) 53 { 54 Logger.Error(ex.ToString()); 55 } 56 return list; 57 } 58 59 public void UpdateUser(Entities.User entity) 60 { 61 Logger.Info($"Updated a User for entity at:{DateTime.Now}"); 62 try 63 { 64 _UserRepository.Update(entity); 65 } 66 catch (Exception ex) 67 { 68 Logger.Error(ex.ToString()); 69 } 70 } 71 } 72 }
9、来到Web目录下,找到brower.json文件,右击选择管理Brower程序包,然后搜索Vue添加,这样就把Vue.js添加到项目中了
10、修改Startup下的OceanNavigationProvider文件,添加代码
1 public override void SetNavigation(INavigationProviderContext context) 2 { 3 context.Manager.MainMenu 4 .AddItem( 5 new MenuItemDefinition( 6 PageNames.Home, 7 L("HomePage"), 8 url: "", 9 icon: "fa fa-home" 10 ) 11 ).AddItem( 12 new MenuItemDefinition( 13 PageNames.About, 14 L("About"), 15 url: "Home/About", 16 icon: "fa fa-info" 17 ) 18 ).AddItem( 19 new MenuItemDefinition( 20 PageNames.User, 21 L("User"), 22 url: "User/Index", 23 icon: "fa fa-user" 24 ) 25 ); 26 }
别忘了打开PageNames文件,添加代码
1 public class PageNames 2 { 3 public const string Home = "Home"; 4 public const string About = "About"; 5 public const string User = "User"; 6 }
11、在Controller文件夹添加控制器UserController
1 namespace Ocean.Web.Controllers 2 { 3 public class UserController : OceanControllerBase 4 { 5 // GET: /<controller>/ 6 public ActionResult Index() 7 { 8 return View(); 9 } 10 } 11 }
并在Views文件夹添加User文件夹并添加Index.cshtml
1 @using Ocean.Web.Startup 2 @{ 3 ViewBag.ActiveMenu = PageNames.User; 4 } 5 6 <div id="userApp"> 7 <div class="row"> 8 <div class="col-md-12"> 9 <button data-toggle="modal" data-target="#userModal" class="btn btn-primary pull-right"><i class="fa fa-plus"></i>添加用户</button> 10 </div> 11 </div> 12 <div class="row"> 13 <table class="table"> 14 <thead> 15 <tr> 16 <th>用户Id</th> 17 <th>用户名</th> 18 <th>真实姓名</th> 19 <th>用户邮箱</th> 20 </tr> 21 </thead> 22 <tbody> 23 <tr v-for="user in userList"> 24 <td><a href="javascript:void(0)" v-on:click="updateUser(user)">{{user.id}}</a></td> 25 <td>{{user.userName}}</td> 26 <td>{{user.realName}}</td> 27 <td>{{user.email}}</td> 28 </tr> 29 </tbody> 30 </table> 31 </div> 32 33 <div class="modal fade" id="userModal" tabindex="-1" role="dialog" data-backdrop="static"> 34 <div class="modal-dialog" role="document"> 35 <div class="modal-content"> 36 <form name="userForm" role="form" novalidate class="form-validation"> 37 <div class="modal-header"> 38 <h4 class="modal-title"> 39 <span v-if="userModel.id">编辑用户</span> 40 <span v-if="!userModel.id">添加用户</span> 41 </h4> 42 </div> 43 <div class="modal-body"> 44 <input type="hidden" v-model="userModel.id" /> 45 <div class="form-group"> 46 <label>用户名</label> 47 <input class="form-control" type="text" v-model="userModel.userName" required> 48 </div> 49 <div class="form-group"> 50 <label>真实姓名</label> 51 <input class="form-control" type="text" v-model="userModel.realName" required> 52 </div> 53 <div class="form-group"> 54 <label>用户邮箱</label> 55 <input class="form-control" type="text" v-model="userModel.email" required> 56 </div> 57 </div> 58 <div class="modal-footer"> 59 <button type="button" class="btn btn-default" data-dismiss="modal">@L("Cancel")</button> 60 <button type="button" class="btn btn-primary blue" v-on:click="createUser"><i class="fa fa-save"></i> <span>@L("Save")</span></button> 61 </div> 62 </form> 63 </div> 64 </div> 65 </div> 66 </div> 67 68 @section scripts{ 69 <script src="~/lib/vue/dist/vue.js"></script> 70 <script src="~/js/views/user/index.js"></script> 71 }
对应位置添加js文件
1 //abp的调用接口abp.services.app.user 2 var _userService = abp.services.app.user; 3 var appVue = new Vue({ 4 el: "#userApp", 5 data: { 6 userModel: { 7 id: 0, 8 userName: '', 9 realName: '', 10 email: '' 11 }, 12 userList: [] 13 }, 14 methods: { 15 getUsers: function () { 16 var own = this; 17 _userService.getUsers().done(function (result) { 18 own.userList = result; 19 }); 20 }, 21 createUser: function () { 22 var own = this; 23 if (own.userModel.id > 0) { 24 _userService.updateUser(own.userModel).done(function () { 25 location.reload(); 26 }) 27 } 28 else { 29 _userService.createUser(own.userModel).done(function () { 30 location.reload(); 31 }); 32 } 33 }, 34 updateUser: function (user) { 35 var own = this; 36 own.userModel = user; 37 $('#userModal').modal(); 38 } 39 } 40 }); 41 appVue.getUsers();
最终效果图
最后:增改查都实现了,就是删除没有实现。删除的实现就靠你们了。我要去巩固Vue.js了