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

<!--category-- ASP.NET, Entity Framework -->
<datetime class="hidden">2024-08-17T20:00</datetime>

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

# परिचय

पिछले भागों में हमने डेटाबेस को कैसे स्थापित करना शामिल किया है-,, कैसे हमारे नियंत्रक और दृश्य संरचना हैं-, & #44; और कैसे हमारी सेवाओं का काम करता है।

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

[TOC]

# डाटाबेस की बीजिंग

पिछले भाग में हम कैसे हम [सेवाओं को आरंभ और सेटअप करें](/blog/addingentityframeworkforblogpostspt2#setup). इस भाग में हम\'\हम कैसे कुछ प्रारंभिक डेटा के साथ डाटाबेस को बीजित करने के लिए कवर करते हैं `EFBlogPopulator` वर्ग. यह वर्ग एक सेवा के रूप में पंजीकृत है `SetupBlog` विस्तार विधि

```csharp
    public async Task Populate()
    {
        var posts = await _markdownBlogService.GetPages();
        var languages = _markdownBlogService.LanguageList();

        var languageEntities = await EnsureLanguages(languages);
        await EnsureCategoriesAndPosts(posts, languageEntities);

        await Context.SaveChangesAsync();
    }
```

आप देख सकते हैं कि में `Populate` विधि हम में बुलाते हैं `_markdownBlogService.GetPages()` यह हमारे makrdown फ़ाइलों के माध्यम से चलाता है और एक गुच्छा populates `BlogViewModels` सभी पदों को समाहित
तब हम भाषाओं के लिए ऐसा ही करते हैं; यह हमारी ओर देखता है `translated` सभी अनुवादित मार्कडाउन फ़ाइलों के लिए फ़ोल्डर जो हमने EasyNMT (से बनाया है [यहाँ](/blog/autotranslatingmarkdownfiles) कैसे हम उस भाग को करते हैं के लिए

## भाषाएँ जोड़ें

फिर हम अपने में बुलाते हैं `EnsureLanguages` विधि जो यह सुनिश्चित करता है कि सभी भाषाएँ डाटाबेस में हैं

```csharp
  private async Task<List<LanguageEntity>> EnsureLanguages(Dictionary<string, List<string>> languages)
    {
        var languageList = languages.SelectMany(x => x.Value).ToList();
        var currentLanguages = await Context.Languages.Select(x => x.Name).ToListAsync();

        var languageEntities = new List<LanguageEntity>();
        var enLang = new LanguageEntity { Name =MarkdownBaseService.EnglishLanguage };

        if (!currentLanguages.Contains(MarkdownBaseService.EnglishLanguage)) Context.Languages.Add(enLang);
        languageEntities.Add(enLang);

        foreach (var language in languageList)
        {
            if (languageEntities.Any(x => x.Name == language)) continue;

            var langItem = new LanguageEntity { Name = language };

            if (!currentLanguages.Contains(language)) Context.Languages.Add(langItem);

            languageEntities.Add(langItem);
        }

        await Context.SaveChangesAsync(); // Save the languages first so we can reference them in the blog posts
        return languageEntities;
    }
```

आप `'`ll देखेंगे यह ppretty सरल है और सिर्फ सुनिश्चित करता है कि सभी भाषाओं हम Markdown पदों से प्राप्त हैं डेटाबेस में हैं `SaveChanges` सुनिश्चित करने के लिए Ids उत्पन्न किए जाते हैं

### श्रेणियों और पदों को जोड़ना

फिर हम अपने में बुलाते हैं `EnsureCategoriesAndPosts` विधि जो सुनिश्चित करता है कि सभी श्रेणियों और पदों के डेटाबेस में हैं

```csharp
    private async Task EnsureCategoriesAndPosts(
        IEnumerable<BlogPostViewModel> posts,
        List<LanguageEntity> languageEntities)
    {
        var languages = languageEntities.ToDictionary(x => x.Name, x => x);
        var currentPosts = await PostsQuery().ToListAsync();
        foreach (var post in posts)
        {
            var existingCategories = Context.Categories.Local.ToList();
            var currentPost =
                currentPosts.FirstOrDefault(x => x.Slug == post.Slug && x.LanguageEntity.Name == post.Language);
            await AddCategoriesToContext(post.Categories, existingCategories);
            existingCategories = Context.Categories.Local.ToList();
            await AddBlogPostToContext(post, languages[post.Language], existingCategories, currentPost);
        }
    }
```

यहाँ हम कंटेक्स्ट का उपयोग करते हैं Context.Categories.Local वर्तमान में कंटेक्ट में जोड़े गए वर्गों को ट्रैक करने के लिए `SaveAsync` कॉल
आप देख सकते हैं कि हम में कॉल `PostsQuery` हमारे आधार वर्ग की विधि जो एक सरल विधि है कि एक क्वेरी करने योग्य के वापस करता है `BlogPostEntity` तो हम पोस्टों के लिए डाटाबेस क्वेरी कर सकते हैं

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

#### वर्ग जोड़ें

फिर हम में बुलाते हैं `AddCategoriesToContext` विधि जो सुनिश्चित करता है कि सभी श्रेणी डाटाबेस में हैं

```csharp
    private async Task AddCategoriesToContext(
        IEnumerable<string> categoryList,
        List<CategoryEntity> existingCategories)
    {
        foreach (var category in categoryList)
        {
            if (existingCategories.Any(x => x.Name == category)) continue;

            var cat = new CategoryEntity { Name = category };

             await Context.Categories.AddAsync(cat);
        }
    }

```

यह फिर से जाँच करता है कि क्या श्रेणी मौजूद है और यदि नहीं यह डाटाबेस में जोड़ता है

#### ब्लॉग पोस्ट्स जोड़ें

फिर हम में बुलाते हैं `AddBlogPostToContext` विधि, यह फिर में कॉल करता है `EFBaseService` डाक को डाटाबेस में सहेजने के लिए

```csharp
    private async Task AddBlogPostToContext(
        BlogPostViewModel post,
        LanguageEntity postLanguageEntity,
        List<CategoryEntity> categories,
        BlogPostEntity? currentPost)
    {
        await SavePost(post, currentPost, categories, new List<LanguageEntity> { postLanguageEntity });
    }
```

हम इसे कॉल करके करते हैं `SavePost` विधि जो एक विधि है, जो डाटाबेस में पोस्ट को सहेजता है

```csharp

   public async Task<BlogPostEntity?> SavePost(BlogPostViewModel post, BlogPostEntity? currentPost =null ,
        List<CategoryEntity>? categories = null,
        List<LanguageEntity>? languages = null)
    {
        if (languages == null)
            languages = await Context.Languages.ToListAsync();

    var postLanguageEntity = languages.FirstOrDefault(x => x.Name == post.Language);
        if (postLanguageEntity == null)
        {
            Logger.LogError("Language {Language} not found", post.Language);
            return null;
        }
        categories ??= await Context.Categories.Where(x => post.Categories.Contains(x.Name)).ToListAsync();
         currentPost ??= await PostsQuery().Where(x=>x.Slug == post.Slug).FirstOrDefaultAsync();
        try
        {
            var hash = post.HtmlContent.ContentHash();
            var currentCategoryNames = currentPost?.Categories.Select(x => x.Name).ToArray() ?? Array.Empty<string>();
            var categoriesChanged = false;
            if (!currentCategoryNames.All(post.Categories.Contains) ||
                !post.Categories.All(currentCategoryNames.Contains))
            {
                categoriesChanged = true;
                Logger.LogInformation("Categories have changed for post {Post}", post.Slug);
            }

            var dateChanged = currentPost?.PublishedDate.UtcDateTime.Date != post.PublishedDate.ToUniversalTime().Date;
            var titleChanged = currentPost?.Title != post.Title;
            if (!titleChanged && !dateChanged && hash == currentPost?.ContentHash && !categoriesChanged)
            {
                Logger.LogInformation("Post {Post} has not changed", post.Slug);
                return currentPost;
            }

            
            var blogPost = currentPost ?? new BlogPostEntity();
            
            blogPost.Title = post.Title;
            blogPost.Slug = post.Slug;
            blogPost.OriginalMarkdown = post.OriginalMarkdown;
            blogPost.HtmlContent = post.HtmlContent;
            blogPost.PlainTextContent = post.PlainTextContent;
            blogPost.ContentHash = hash;
            blogPost.PublishedDate = post.PublishedDate;
            blogPost.LanguageEntity = postLanguageEntity;
            blogPost.Categories = categories.Where(x => post.Categories.Contains(x.Name)).ToList();

            if (currentPost != null)
            {
                Logger.LogInformation("Updating post {Post}", post.Slug);
                Context.BlogPosts.Update(blogPost); // Update the existing post
            }
            else
            {
                Logger.LogInformation("Adding new post {Post}", post.Slug);
                Context.BlogPosts.Add(blogPost); // Add a new post
            }
            return blogPost;
        }
        catch (Exception e)
        {
            Logger.LogError(e, "Error adding post {Post}", post.Slug);
        }

        return null;
    }

```

जैसा कि आप देख सकते हैं यह परिवर्तन की खोज का LOT है सुनिश्चित करने के लिए हम नहीं कर रहे हैं।

ध्यान देने के लिए एक बात यह है कि कैसे एक DateTimeOffset की जाँच करने में परेशानी है हम इसे यूटीसी में रूपांतरित करना चाहते हैं और फिर इसे तुलना करने के लिए तिथि प्राप्त करें। `DateTimeOffset` एक समय घटक है और हम सिर्फ तारीख को तुलना करना चाहते हैं

```csharp
var dateChanged = currentPost?.PublishedDate.UtcDateTime.Date != post.PublishedDate.ToUniversalTime().Date;
```

# अंत में

अब हम एक पूरी तरह से काम कर रहे ब्लॉग सिस्टम है जो मार्कडाउन फ़ाइलों और अनुवादित मार्कडॉन फ़ाइलें से populated किया जा सकता है