• 當前位置:首頁 > IT技術 > Windows編程 > 正文

    《ASP.ENT Core 與 RESTful API 開發實戰》-- (第5章)-- 讀書筆記(中)
    2021-10-22 16:54:12


    第 5 章 使用 Entity Framework Core

    5.3 重構倉儲類

    創建一個通用倉儲接口

    namespace Library.API.Services
    {
    public interface IRepositoryBase<T>
    {
    Task<IEnumerable<T>> GetAllAsync();
    Task<IEnumerable<T>> GetByConditionAsync(Expression<Func<T, bool>> expression);
    void Create(T entity);
    void Update(T entity);
    void Delete(T entity);
    Task<bool> SaveAsync();
    }
    }


    繼續創建一個接口

    namespace Library.API.Services
    {
    public interface IRepositoryBase2<T,TId>
    {
    Task<T> GetByIdAsync(TId id);
    Task<bool> IsExistAsync(TId id);
    }
    }


    添加 RepositoryBase 類并實現上面兩個接口

    namespace Library.API.Services
    {
    public class RepositoryBase<T, TId> : IRepositoryBase<T>, IRepositoryBase2<T, TId> where T : class
    {
    public DbContext DbContext { get; set; }

    public RepositoryBase(DbContext dbContext)
    {
    DbContext = dbContext;
    }

    public Task<IEnumerable<T>> GetAllAsync()
    {
    return Task.FromResult(DbContext.Set<T>().AsEnumerable());
    }

    public Task<IEnumerable<T>> GetByConditionAsync(Expression<Func<T, bool>> expression)
    {
    return Task.FromResult(DbContext.Set<T>().Where(expression).AsEnumerable());
    }

    public void Create(T entity)
    {
    DbContext.Set<T>().Add(entity);
    }

    public void Update(T entity)
    {
    DbContext.Set<T>().Update(entity);
    }

    public void Delete(T entity)
    {
    DbContext.Set<T>().Remove(entity);
    }

    public async Task<bool> SaveAsync()
    {
    return await DbContext.SaveChangesAsync() > 0;
    }

    public async Task<T> GetByIdAsync(TId id)
    {
    return await DbContext.Set<T>().FindAsync(id);
    }

    public async Task<bool> IsExistAsync(TId id)
    {
    return await DbContext.Set<T>().FindAsync(id) != null;
    }
    }
    }


    這里需要注意的是,EF Core 對于查詢的執行采用延遲執行的方法,只有遇到了實際需要結果的操作,查詢才會執行,這些操作包括以下幾種類型:

    • 對結果使用 for 或 foreach 循環
    • 使用了 ToList()、ToArray() 和 ToDictionary() 等方法
    • 使用了 Single()、Count()、Average、First() 和 Max() 等方法

    創建其他倉儲接口

    public interface IAuthorRepository : IRepositoryBase<Author>, IRepositoryBase2<Author, Guid>


    創建實現類

    namespace Library.API.Services
    {
    public class AuthorRepository : RepositoryBase<Author, Guid>, IAuthorRepository
    {
    public AuthorRepository(DbContext dbContext) : base(dbContext)
    {
    }
    }
    }


    以同樣的方式創建 IBookRepository 與 BookRepository

    接著創建倉儲包裝器 IRepositoryWrapper 及其實現

    namespace Library.API.Services
    {
    public interface IRepositoryWrapper
    {
    IBookRepository Book { get; }
    IAuthorRepository Author { get; }
    }
    }

    namespace Library.API.Services
    {
    public class RepositoryWrapper : IRepositoryWrapper
    {
    public LibraryDbContext LibraryDbContext { get; }

    private IAuthorRepository _authorRepository = null;
    private IBookRepository _bookRepository = null;

    public RepositoryWrapper(LibraryDbContext libraryDbContext)
    {
    LibraryDbContext = libraryDbContext;
    }

    public IAuthorRepository Author => _authorRepository ?? new AuthorRepository(LibraryDbContext);
    public IBookRepository Book => _bookRepository ?? new BookRepository(LibraryDbContext);
    }
    }


    包裝器提供了所有倉儲接口的統一訪問方式,從而避免了單獨訪問每個倉儲接口

    接下來要將包裝器放到容器中,在 ConfigureServices 注入

    services.AddScoped<IRepositoryWrapper, RepositoryWrapper>();


    5.4 重構 Controller 和 Action

    在重構之前,引入對象映射庫 AutoMapper

    Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection


    在 ConfigureServices 注入

    services.AddAutoMapper(typeof(Startup));


    為了 AutoMapper 正確執行對象映射,需要創建一個 Profile 類的派生類,用以說明映射的對象以及映射規則

    namespace Library.API.Helpers
    {
    public class LibraryMappingProfile : Profile
    {
    public LibraryMappingProfile()
    {
    CreateMap<Author, AuthorDto>()
    .ForMember(dest => dest.Age, config =>
    config.MapFrom(src => src.BirthData.GetCurrentAge()));
    CreateMap<Book, BookDto>();
    CreateMap<AuthorForCreationDto, Author>();
    CreateMap<BookForCreationDto, Book>();
    CreateMap<BookForUpdateDto, Book>();
    }
    }
    }


    CreateMap 方法的兩個泛型參數分別指明對象映射中的源和目標,當從數據庫中獲取數據時,實體類為源,而 DTO 為目標;當處理請求時相反

    當程序運行時,執行 AddAutoMapper 方法時會掃描指定程序集中 Profile 類的派生類,并根據掃描結果生成映射規則

    《ASP.ENT Core 與 RESTful API 開發實戰》-- (第5章)-- 讀書筆記(中)_javascript


    本文摘自 :https://blog.51cto.com/u

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码