Het 'Entity Framework' toevoegen voor Blog Posts (Part 5) (Nederlands (Dutch))

Het 'Entity Framework' toevoegen voor Blog Posts (Part 5)

Sunday, 18 August 2024

//

6 minute read

Zie delen 1 en 2 en 3 en 4 voor de vorige stappen.

Inleiding

In eerdere delen hebben we behandeld hoe de database op te zetten, hoe onze controllers en aansigten zijn gestructureerd, hoe ons service werkte , en hoe je de database met een aantal begingegevens opbouwtM SK3 In deze deel zullen we de details over hoe de EF-gebaseerde diensten werken en hoe we ze kunnen gebruiken in ons controllersMSC5

Zoals gewoonlijk zie je hier alle bronnen voor op mijn GitHub. Hier., in de meest duidelijke folder/BloggidsM SK2

Blogdiensten

Lêergebaseerde Diensten

Vroeger gebruikten we een MarkdownBlogService om onze blogposts en talen te krijgen. Deze dienst werd geïnjecteerd in onze controllers en aansigten. Deze service was een eenvoudige dienst die afteken-bestanden van disket las en ze terugvoerde als BlogViewModels.

Dit gebruikte een statisch woordenboek om de blogposts te houden en dan terugvoerde het resultaat van dat woordenboek.

  public async Task<PostListViewModel> GetPagedPosts(int page = 1, int pageSize = 10, string language = EnglishLanguage)
    {
        var model = new PostListViewModel();
        var posts = GetPageCache().Where(x => x.Value.Language == language)
            .Select(x => GetListModel(x.Value)).ToList();
        model.Posts = posts.OrderByDescending(x => x.PublishedDate).Skip((page - 1) * pageSize).Take(pageSize).ToList();
        model.TotalItems = posts.Count();
        model.PageSize = pageSize;
        model.Page = page;
        return await Task.FromResult(model);
    }

Dit is de GetPagedPosts methode van de MarkdownBlogService. Deze methode haalt de blogposts uit de cache en geeft ze terug als een PostListViewModel.

Het gebruik van Files voor het opslaan van Markdown-bestanden is nog steeds een goede aanpak, het maakt het makkelijk om posten toe te voegen ( Ik stoor gewoon markdown- bestanden op de schijf en check ze in ) en hetMSC3 is gemakkelijk te beherenM SK4 Maar we willen de database gebruiken om de posten en talen op te slaan

flowchart LR
    A[Write New Markdown File] -->|Checkin To Github| B(Github Action Triggers) -->  C(Builds Docker Image) --> D(Watchtower Pulls new Image) --> E(Site Updated)
   
  

EF-gebaseerde diensten

In de [Vorige deel]((/blog/addingentityframeworkforblogpostspt 4) Ik liet zien hoe we de database met de blogdata zaaidenM SK3 Dit updates elke keer dat we de dockercontainer herontplooien en herlaten.Met behulp van de waarnemingstoren. ) We gebruikten een EFBlogPopulator Class om dit te doen.

Onze stroom ziet er zo uit.

   flowchart TD
    A[Write New Markdown File] -->|Checkin To Github| B(Github Action Triggers)
    B --> C(Builds Docker Image)
    C --> D(Watchtower Pulls new Image)
    D --> E{New Files Added?}
    E -->|Yes| F(Add File to Database)
    E -->|No| G(Skip Database Seeding)
    F --> H(Site Updated)
    G --> H(Site Updated)

Nu we de blogposts in onze database hebben, gebruiken we de EFBlogService om de implementatie voor uit te voeren. IBlogService interface:

public interface IBlogService
{
   Task<List<string>> GetCategories();
    Task<List<BlogPostViewModel>> GetPosts(DateTime? startDate = null, string category = "");
    Task<PostListViewModel> GetPostsByCategory(string category, int page = 1, int pageSize = 10, string language = MarkdownBaseService.EnglishLanguage);
    Task<BlogPostViewModel?> GetPost(string slug, string language = "");
    Task<PostListViewModel> GetPagedPosts(int page = 1, int pageSize = 10, string language = MarkdownBaseService.EnglishLanguage);
    
    Task<List<PostListModel>> GetPostsForLanguage(DateTime? startDate = null, string category = "", string language = MarkdownBaseService.EnglishLanguage);
}

Dit is de IBlogService interface. Dit is de interface die onze controllers gebruiken om de blogposts te krijgen. EFBlogService Die implementeert deze interface en gebruikt de BlogContext om de gegevens uit de database te krijgen. Net als bij Out FileBased service Bovenaan We kunnen posten krijgen per categorie, per taal, per datumM SK2 en gepoogd .

GetPostList

    private async Task<PostListViewModel> GetPostList(int count, List<BlogPostEntity> posts, int page, int pageSize)
    {
        var languages = await NoTrackingQuery().Select(x =>
                new { x.Slug, x.LanguageEntity.Name }
            ).ToListAsync();

        var postModels = new List<PostListModel>();

        foreach (var postResult in posts)
        {
            var langArr = languages.Where(x => x.Slug == postResult.Slug).Select(x => x.Name).ToArray();

            postModels.Add(postResult.ToListModel(langArr));
        }

        var postListViewModel = new PostListViewModel
        {
            Page = page,
            PageSize = pageSize,
            TotalItems = count,
            Posts = postModels
        };

        return postListViewModel;
    }

Hier gebruiken we onze gemeenschappelijke PostsQuery Maar we voegen er nog meer toe. NoTrackingQuery Het is een eenvoudige methode die een vraagbaar antwoord terugbrengt. BlogPostEntity Maar met AsNoTrackingWithIdentityResolution added. Dit betekent dat de entiteiten niet getrackd worden door de context en alleen gelezen worden.

     protected IQueryable<BlogPostEntity> PostsQuery()=>Context.BlogPosts.Include(x => x.Categories)
        .Include(x => x.LanguageEntity);
     
         private IQueryable<BlogPostEntity> NoTrackingQuery() => PostsQuery().AsNoTrackingWithIdentityResolution();

Je kunt zien dat we ook de talen voor de posten krijgen en dan een PostListViewModel Het is een structuur die paging-informatie accepteert.Page, PageSize en TotalItems) en wordt teruggestuurd aan de controller

GetPost

Onze belangrijkste methode is de GetPost De methode die een enkele post krijgt door zijn Slug en Language. Dit is een eenvoudige methode die de PostsQuery om de post te krijgen en dan terug te geven. BlogPostViewModel. Je kunt zien dat het ook een optioneel systeem heeft. Language parameters die standaard zijn. EnglishLanguage Dat is een constante in ons systeem. MarkdownBaseService Klas.

  public async Task<BlogPostViewModel?> GetPost(string slug, string language = "")
    {
        if (string.IsNullOrEmpty(language)) language =MarkdownBaseService.EnglishLanguage;
        var post = await NoTrackingQuery().FirstOrDefaultAsync(x => x.Slug == slug && x.LanguageEntity.Name == language);
        if (post == null) return null;
        var langArr = await GetLanguagesForSlug(slug);
        return post.ToPostModel(langArr);
    }

Dit gebruikt ook onze gemeenschappelijke methode. GetLanguagesForSlug Dit is een eenvoudige methode die de talen voor een post teruggeeft.

    private async Task<List<string>> GetLanguagesForSlug(string slug)=> await NoTrackingQuery()
        .Where(x => x.Slug == slug).Select(x=>x.LanguageEntity.Name).ToListAsync();

GetPostsByCategory

Deze methode krijgt de posten per categorie ( zoals ASP.NET & Het entiteitsraamwerk voor deze post PostsQuery om de posten te krijgen en ze te filteren volgens de categorie. Het geeft dan de posts terug als een PostListViewModel.

    public async Task<PostListViewModel> GetPostsByCategory(string category, int page = 1, int pageSize = 10,
        string language = MarkdownBaseService.EnglishLanguage)
    {
        
        var count = await NoTrackingQuery()
            .Where(x => x.Categories.Any(c => c.Name == category) && x.LanguageEntity.Name == language).CountAsync();
        var posts = await PostsQuery()
            .Where(x => x.Categories.Any(c => c.Name == category) && x.LanguageEntity.Name == language)
            .Skip((page - 1) * pageSize)
            .Take(pageSize)
            .ToListAsync();

        var languages = await GetLanguagesForSlugs(posts.Select(x => x.Slug).ToList());
        var postListViewModel = new PostListViewModel
        {
            Page = page,
            PageSize = pageSize,
            TotalItems = count,
            Posts = posts.Select(x => x.ToListModel(
                languages.FirstOrDefault(entry => entry.Key == x.Slug).Value.ToArray())).ToList()
        };
        return postListViewModel;
    }

In slotting:

Je kunt zien dat de EF-gebaseerde diensten een beetje complexer zijn dan de File Based-diensten, maar ze zijn flexibeler en kunnen worden gebruikt in complexere scenario's. We kunnen de ES-geBaseerde diensten gebruiken in onze controllers en aanzichten om de blogposts en talen te krijgen. In de toekomst bouwen we op deze en voegen andere diensten toe, zoals inline-bewerking en commentaar. We zullen ook kijken hoe we deze over meerdere systemen kunnen synchroniseren.

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.