用VSCode開發一個基於asp.net core 2.0/sql server linux(docker)/ng5/bs4的項目(3)

第一部分: http://www.cnblogs.com/cgzl/p/8478993.htmlhtml

第二部分: http://www.cnblogs.com/cgzl/p/8481825.html面試

因爲本文主要是講VSCode開發等, 因此相關等一些angular/.net core的知識就相對少講點.數據庫

我把需求改一下, 如圖:api

因爲efcore目前仍是使用中間表來創建多對多的關係, 因此分類標籤這個需求就沒什麼特別的了, 就去掉吧. 還有電視劇分季這個技術上也是重複的, 也刪掉.app

目前只剩下電視臺和電視劇的維護, 還剩下的知識點是:async

  • 集合的CRUD操做
  • 對項目結構進行整理, 使用Unit Of Work 以及 Repository 模式
  • 上傳文件

因爲CRUD畫面作起來比較簡單, 我相信你們使用該技術的都會, 因此我直接把我寫完的代碼傳上來. 此時頁面的操做效果請看視頻:post

這時的代碼: this

https://pan.baidu.com/s/1egCmuNT0OxJNwkz0OQ72kAspa

這裏面又一個比較常見的問題, 就是.net

針對集合的增刪改:

上述業務的電視劇的增刪改就會出現這種狀況:

數據庫裏面原來有4條數據, 而前臺操做完, 刪除了第3條數據, 而且增長了一條數據, 其他數據的內容可能有變化.

這種集合類增刪改的思路應該是這樣的:

1.從傳進來的集合找出全部新添加的數據(新添加的數據Id一般並不存在, 這是條件), 放在一個臨時的集合, 而後添加到context.

2.從數據庫集合找出全部須要刪除的數據(有一些id在傳進來的集合找不到的就是), 放在一個集合, 而後從conetxt一次性移除.

3.兩個集合都有的數據就是隻須要修改內容的數據, 更新便可.

下面開始實現這個功能:

首先確保Put方法裏, 把電視臺下全部的電視劇都讀取出來:

 

接下來, 找到MappingProfile.cs, 使用AutoMapper來實現這個功能.

首先要忽略默認的集合映射:

而後調用AfterMap方法作後期手動處理, 代碼的意思大概是這樣:

或者, 也能夠用Linq作一些重構:

回到畫面試一下編輯功能:

而後添加和刪除:

查看結果:

OK.

 

項目重構

下面, 咱們使用Unit Of Work以及Repository Pattern對項目進行重構:

因爲這部分也很簡單, 而且也不是這篇文章的重點, 我就直接貼出重構後的代碼吧:

Database/TvRepostiory.cs:

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Tv.Models;

namespace Tv.Database
{
    public class TvRepository : ITvRepostitory
    {
        private readonly TvContext context;

        public TvRepository(TvContext context)
        {
            this.context = context;
        }

        public async Task<List<TvNetwork>> GetTvNetworksAsync()
        {
            return await context.TvNetworks.Include(x => x.TvShows).ToListAsync();
        }

        public async Task<TvNetwork> GetTvNetworkByIdAsync(int id, bool includeRelated = true)
        {
            if (includeRelated)
            {
                return await context.TvNetworks.Include(x => x.TvShows).SingleOrDefaultAsync(x => x.Id == id);
            }
            return await context.TvNetworks.FindAsync(id);
        }

        public void AddTvNetwork(TvNetwork model)
        {
            context.TvNetworks.Add(model);
        }

        public void RemoveTvNetwork(TvNetwork model)
        {
            context.TvNetworks.Remove(model);
        }
    }
}

Database/ITvRepository.cs:

using System.Collections.Generic;
using System.Threading.Tasks;
using Tv.Models;

namespace Tv.Database
{
    public interface ITvRepostitory
    {
        Task<List<TvNetwork>> GetTvNetworksAsync();
        Task<TvNetwork> GetTvNetworkByIdAsync(int id, bool includeRelated = true);
        void AddTvNetwork(TvNetwork model);
        void RemoveTvNetwork(TvNetwork model);
    }
}

Database/UnitOfWork.cs:

using System.Threading.Tasks;

namespace Tv.Database
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly TvContext context;

        public UnitOfWork(TvContext context)
        {
            this.context = context;
        }

        public async Task SaveAsync()
        {
            await context.SaveChangesAsync();
        }
    }
}

Database/IUnitOfWork.cs:

using System.Threading.Tasks;

namespace Tv.Database
{
    public interface IUnitOfWork
    {
        Task SaveAsync();
    }
}

Startup.cs:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddAutoMapper();
            // services.AddDbContext<TvContext>(opt => opt.UseSqlServer(Configuration["ConnectionStrings:Default"]));
            services.AddDbContext<TvContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("Default")));
            services.AddScoped<ITvRepostitory, TvRepository>();
            services.AddScoped<IUnitOfWork, UnitOfWork>();
            services.AddMvc();
        }

TvController.cs:

using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Tv.Database;
using Tv.Models;
using Tv.ViewModels;

namespace Tv.Controllers
{
    public class TvController : Controller
    {
        private readonly ITvRepostitory repostiory;
        private readonly IUnitOfWork unitOfWork;
        private readonly IMapper mapper;

        public TvController(ITvRepostitory repostiory, IUnitOfWork unitOfWork, IMapper mapper)
        {
            this.repostiory = repostiory;
            this.unitOfWork = unitOfWork;
            this.mapper = mapper;
        }

        [HttpGet("api/tvnetworks")]
        public async Task<IEnumerable<TvNetworkViewModel>> GetTvNetworks()
        {
            var models = await repostiory.GetTvNetworksAsync();
            var vms = mapper.Map<List<TvNetwork>, List<TvNetworkViewModel>>(models);
            return vms;
        }

        [HttpGet("api/tvnetworks/{id}")]
        public async Task<IActionResult> Get(int id)
        {
            var model = await repostiory.GetTvNetworkByIdAsync(id);
            var vm = mapper.Map<TvNetwork, TvNetworkViewModel>(model);
            return Ok(vm);
        }

        [HttpPost("api/tvnetworks")]
        public async Task<IActionResult> Post([FromBody]TvNetworkUpdateViewModel vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var model = mapper.Map<TvNetworkUpdateViewModel, TvNetwork>(vm);
            repostiory.AddTvNetwork(model);
            await unitOfWork.SaveAsync();
            var result = mapper.Map<TvNetwork, TvNetworkViewModel>(model);
            return Ok(result);
        }

        [HttpPut("api/tvnetworks/{id}")]
        public async Task<IActionResult> Put(int id, [FromBody]TvNetworkUpdateViewModel vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var dbModel = await repostiory.GetTvNetworkByIdAsync(id);
            if (dbModel == null)
            {
                return NotFound();
            }
            var model = mapper.Map<TvNetworkUpdateViewModel, TvNetwork>(vm, dbModel);
            await unitOfWork.SaveAsync();
            var result = mapper.Map<TvNetwork, TvNetworkViewModel>(model);
            return Ok(result);
        }

        [HttpDelete("api/tvnetworks/{id}")]
        public async Task<IActionResult> Delete(int id)
        {
            var model = await repostiory.GetTvNetworkByIdAsync(id, includeRelated: false);
            if (model == null)
            {
                return NotFound();
            }
            repostiory.RemoveTvNetwork(model);
            await unitOfWork.SaveAsync();
            return NoContent();
        }
    }
}

 

再操做下畫面, 沒有任何問題.

 

 

今天先寫到這, VSCode的開發速度仍是很是快的.

還剩下最後一部分--上傳文件.

相關文章
相關標籤/搜索