ब्लॉग पोस्टों के लिए अस्तित्व फ्रेमवर्क जोड़ना
भाग देखें 1 और 2 और 3 और 4 पिछले चरणों के लिए
परिचय
पिछले भागों में हमने यह बताया कि कैसे डाटाबेस स्थापित किया जाता है।
जैसा कि आमतौर पर आप इस के लिए सभी स्रोत मेरी GitHub पर देख सकते हैं यहाँMostlylucid में ,Blog फ़ोल्डर
ब्लॉग सेवाएँ
फ़ाइल आधारित सेवाएँ
पहले हम एक का उपयोग किया MarkdownBlogService हमारे ब्लॉग पोस्ट और भाषाओं को प्राप्त करने के लिए. यह सेवा हमारे नियंत्रकों और दृश्यों में इंजेक्शन किया गया था। BlogViewModels.
यह एक स्थिर शब्दकोश का उपयोग करता है कि ब्लॉग पोस्टों को रखने के लिए फिर उस शब्दकोष से परिणाम लौटाया
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.
मार्क डाउन फ़ाइलों को भंडारित करने के लिए फ़ाइल का उपयोग अभी भी एक अच्छा दृष्टिकोण है
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) मैंने दिखाया कि हम कैसे ब्लॉग डेटा के साथ डाटाबेस को बीजित किया है।निगरानी टावर का उपयोग करते हुए ) हमने एक उपयोग किया EFBlogPopulator इस करने के लिए वर्ग.
अब हमारे प्रवाह इस तरह दिखता है
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 इंटरफेस
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 डाटाबेस से डेटा प्राप्त करने के लिए
बाहर फ़ाइल आधारित सेवा के रूप में ऊपर हम श्रेणी के अनुसार पोस्ट प्राप्त कर सकते हैं
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;
}
यहाँ हम अपने सामान्य का उपयोग करते हैं PostsQuery लेकिन हम जोड़ते हैं NoTrackingQuery जो एक सरल विधि है कि एक क्वेरी करने योग्य के वापस करता है BlogPostEntity लेकिन साथ AsNoTrackingWithIdentityResolution जोड़ा गया. इसका मतलब है कि अस्तित्व संदर्भ द्वारा ट्रैक नहीं किए जाते हैं और सिर्फ पढ़ने के लिए हैं
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 वर्ग
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 जो एक पोस्ट के लिए भाषाओं को प्राप्त करता है
private async Task<List<string>> GetLanguagesForSlug(string slug)=> await NoTrackingQuery()
.Where(x => x.Slug == slug).Select(x=>x.LanguageEntity.Name).ToListAsync();
GetPostsByCategory
यह विधि इस पोस्ट के लिए अस्तित्व फ्रेमवर्क का उपयोग करता है PostsQuery पोस्ट्स प्राप्त करने के लिए और फिर उन्हें श्रेणी के द्वारा फ़िल्टर करता है. यह फिर एक के रूप में पोस्ट्स लौटाता है 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;
}
अंत में
आप देख सकते हैं कि एफ आधारित सेवा फ़ाइल आधारित सेवाओं से कुछ अधिक जटिल है लेकिन वे अधिक लचीला हैं और अधिक जटिल परिदृश्यों में उपयोग किया जा सकता है। भविष्य में हम इन पर निर्माण करेंगे और इनलाइन संपादन तथा टिप्पणी जैसे सेवाएं जोड़ेंगे हम यह भी देखेंगे कि कैसे हम इन को बहुविध प्रणालियों के बीच समक्रमित कर सकते हैं