# ब्लॉग पोस्टों के लिए अस्तित्व फ्रेमवर्क जोड़ना

<!--category-- ASP.NET, Entity Framework -->
<datetime class="hidden">2024-08-18T01:20</datetime>

भाग देखें [1](/blog/addingentityframeworkforblogpostspt1) और [2](/blog/addingentityframeworkforblogpostspt2) और [3](/blog/addingentityframeworkforblogpostspt3) और [4](/blog/addingentityframeworkforblogpostspt4) पिछले चरणों के लिए

# परिचय

पिछले भागों में हमने यह बताया कि कैसे डाटाबेस स्थापित किया जाता है।

जैसा कि आमतौर पर आप इस के लिए सभी स्रोत मेरी GitHub पर देख सकते हैं [यहाँ](https://github.com/scottgal/mostlylucidweb/tree/main/Mostlylucid/Blog)Mostlylucid में ,Blog फ़ोल्डर

[TOC]

# ब्लॉग सेवाएँ

## फ़ाइल आधारित सेवाएँ

पहले हम एक का उपयोग किया `MarkdownBlogService` हमारे ब्लॉग पोस्ट और भाषाओं को प्राप्त करने के लिए. यह सेवा हमारे नियंत्रकों और दृश्यों में इंजेक्शन किया गया था। `BlogViewModels`.

यह एक स्थिर शब्दकोश का उपयोग करता है कि ब्लॉग पोस्टों को रखने के लिए फिर उस शब्दकोष से परिणाम लौटाया

```csharp
  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);
    }
```

यह है `GetPagedPosts` विधि से `MarkdownBlogService`. यह विधि कैश से ब्लॉग पोस्ट पाता है और उन्हें एक के रूप में वापस करता है `PostListViewModel`.

मार्क डाउन फ़ाइलों को भंडारित करने के लिए फ़ाइल का उपयोग अभी भी एक अच्छा दृष्टिकोण है

```mermaid
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)
   
  
```

## ईएफ आधारित सेवाएं

में [पिछला भाग]((/blogM SK1addingentityframeworkforblogpostspt4) मैंने दिखाया कि हम कैसे ब्लॉग डेटा के साथ डाटाबेस को बीजित किया है।[निगरानी टावर का उपयोग करते हुए ](blog/dockercompose)) हमने एक उपयोग किया `EFBlogPopulator` इस करने के लिए वर्ग.

अब हमारे प्रवाह इस तरह दिखता है

```mermaid
   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)

```

अब कि हम अपने डाटाबेस में ब्लॉग पोस्ट है हम उपयोग कर रहे हैं `EFBlogService` बाहर के लिए कार्यान्वयन उपलब्ध कराना `IBlogService` इंटरफेस

```csharp
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);
}
```

यह है `IBlogService` इन्टरफेस. यह इन्टरफ़ेस है कि हमारे नियंत्रक ब्लॉग पोस्ट्स प्राप्त करने के लिए प्रयोग करते हैं `EFBlogService` इस इंटरफेस को लागू करता है और `BlogContext` डाटाबेस से डेटा प्राप्त करने के लिए
बाहर फ़ाइल आधारित सेवा के रूप में [ऊपर](#file-based-services) हम श्रेणी के अनुसार पोस्ट प्राप्त कर सकते हैं

### `GetPostList`

```csharp
    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;
    }
```

यहाँ हम अपने सामान्य का उपयोग करते हैं `PostsQuery` लेकिन हम जोड़ते हैं `NoTrackingQuery` जो एक सरल विधि है कि एक क्वेरी करने योग्य के वापस करता है `BlogPostEntity` लेकिन साथ `AsNoTrackingWithIdentityResolution` जोड़ा गया. इसका मतलब है कि अस्तित्व संदर्भ द्वारा ट्रैक नहीं किए जाते हैं और सिर्फ पढ़ने के लिए हैं

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

आप देख सकते हैं कि हम भी पोस्टों के लिए भाषाओं को मिलता है और फिर एक `PostListViewModel` जो एक संरचना है जो पेजिंग सूचना स्वीकार करता है (`Page`, `PageSize` और `TotalItems`) और नियंत्रक को लौटाया जाता है

### `GetPost`

हमारा मुख्य तरीका है `GetPost` विधि जो अपने द्वारा एक एकल पद प्राप्त करता है `Slug` और `Language`. यह एक सरल विधि है कि उपयोग करता है `PostsQuery` पोस्ट प्राप्त करने के लिए और फिर इसे एक के रूप में वापस करता है `BlogPostViewModel`.
आप देख सकते हैं कि यह भी एक वैकल्पिक है `Language` पैरामीटर जो डिफ़ॉल्ट है `EnglishLanguage` जो हमारे में एक स्थिर है `MarkdownBaseService` वर्ग

```csharp
  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);
    }
```

यह भी हमारे आम तरीके का उपयोग करता है `GetLanguagesForSlug` जो एक पोस्ट के लिए भाषाओं को प्राप्त करता है

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

### `GetPostsByCategory`

यह विधि इस पोस्ट के लिए अस्तित्व फ्रेमवर्क का उपयोग करता है `PostsQuery` पोस्ट्स प्राप्त करने के लिए और फिर उन्हें श्रेणी के द्वारा फ़िल्टर करता है. यह फिर एक के रूप में पोस्ट्स लौटाता है `PostListViewModel`.

```csharp
    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;
    }
```

# अंत में

आप देख सकते हैं कि एफ आधारित सेवा फ़ाइल आधारित सेवाओं से कुछ अधिक जटिल है लेकिन वे अधिक लचीला हैं और अधिक जटिल परिदृश्यों में उपयोग किया जा सकता है।
भविष्य में हम इन पर निर्माण करेंगे और इनलाइन संपादन तथा टिप्पणी जैसे सेवाएं जोड़ेंगे
हम यह भी देखेंगे कि कैसे हम इन को बहुविध प्रणालियों के बीच समक्रमित कर सकते हैं