There’s a ton of small bug fixes in this release, quite a few enhancements and a few larger new features. Configuration performance went up quite a bit, and I’ve laid the groundwork to make in-memory mapping a lot faster in the future. LINQ projection has gotten to the point where you can do anything that the major query providers support.
همه چیز درباره الگوی طراحی Singleton
Singleton design pattern is one of the simplest design patterns: it involves only one class throughout the application which is responsible to instantiate itself, to make sure it creates not more than one instance; in the same time it provides a global point of access to that instance. In this case the same instance can be used from everywhere, being impossible to invoke directly the constructor each time.
پیشنهاد طراحی ++C امن
public abstract class BaseEntity { #region Properties /// <summary> /// gets or sets Identifier of this Entity /// </summary> public virtual long Id { get; set; } /// <summary> /// gets or sets date that this entity was created /// </summary> public virtual DateTime CreatedOn { get; set; } /// <summary> /// gets or sets Date that this entity was updated /// </summary> public virtual DateTime ModifiedOn { get; set; } /// <summary> /// indicate this entity is Locked for Modify /// </summary> public virtual bool ModifyLocked { get; set; } /// <summary> /// gets or sets date that this entity repoted last time /// </summary> public virtual DateTime? ReportedOn { get; set; } /// <summary> /// gets or sets counter for Content's report /// </summary> public virtual int ReportsCount { get; set; } /// <summary> /// gets or sets TimeStamp for prevent concurrency Problems /// </summary> public virtual byte[] RowVersion { get; set; } #endregion #region NavigationProperties /// <summary> /// gets ro sets User that Modify this entity /// </summary> public virtual User ModifiedBy { get; set; } /// <summary> /// gets ro sets Id of User that modify this entity /// </summary> public virtual long? ModifiedById { get; set; } /// <summary> /// gets ro sets User that Create this entity /// </summary> public virtual User CreatedBy { get; set; } /// <summary> /// gets ro sets User that Create this entity /// </summary> public virtual long CreatedById { get; set; } #endregion }
- ReportedOn : نگهداری آخرین تاریخ اخطار
- ModifyLocked : به منظور ممانعت از ویرایش
- CreatedBy,CreatedById : به منظور ایجاد ارتباط یک به چند بین کاربر و سایر موجودیتها (به عنوان ایجاد کننده)
- ModifiedBy , ModifiedById : به منظور ایجاد ارتباط یک به چند بین کاربر و سایر موجودیتها (به عنوان آخرین تغییر دهنده)
مدل کلکسیون (کالکشن ،Collection)
/// <summary> /// Represents the Collection for group posts by topic /// </summary> public class Collection : GuidBaseEntity { #region Properties /// <summary> /// gets or sets name of collection /// </summary> public virtual string Name { get; set; } /// <summary> /// gets or sets Alternative SlugUrl /// </summary> public virtual string SlugUrl { get; set; } /// <summary> /// gets or sets some description of group /// </summary> public virtual string Description { get; set; } /// <summary> /// gets or sets description that indicate how to pay /// </summary> public virtual string HowToPay { get; set; } /// <summary> /// gets or sets Visibility Type /// </summary> public virtual CollectionVisibility Visibility { get; set; } /// <summary> /// gets or sets color of Collection's Cover /// </summary> public virtual string Color { get; set; } /// <summary> /// gets or sets Name of Image that used as Cover /// </summary> public virtual string Photo { get; set; } /// <summary> /// gets or sets name of tags seperated by comma that assosiated with this content fo increase performance /// </summary> public virtual string TagNames { get; set; } /// <summary> /// indicate this collection is active or not /// </summary> public virtual bool IsActive { get; set; } #endregion #region NavigationProperties /// <summary> /// get or set collection of attachments that attached in this group /// </summary> public virtual ICollection<CollectionAttachment> Attachments { get; set; } /// <summary> /// get or set tags of collection /// </summary> public virtual ICollection<Tag> Tags { get; set; } /// <summary> /// get or set List Of Posts that Associated with this Collection /// </summary> public virtual ICollection<CollectionPost> Posts { get; set; } /// <summary> /// get or set Users that they are Member of this collection if visibility is Custom /// </summary> public virtual ICollection<User> Memebers { get; set; } #endregion } public enum CollectionVisibility { Friends, OnlyMe, Public, NotFree, Custom }
- Visibility : برای اعمال محدودیت دسترسی به یک کلکسیون در نظر گرفته شده است. از نوع، نوع دادهی شمارشی CollectionVisibility پیاده سازی شدهی دربالا، میباشد. حالت Custom برای زمانی است که نیاز است صرفا یک سری از کاربران بدون هزینه، دسترسی برای مطالعهی این کلکسیون داشته باشند. حالت NotFree هم برای زمانی است که کاربرانی که هزینهی مورد نظر را پرداخت کرده باشند، به عنوان عضو به این کلکسیون میتوانند دسترسی داشته باشند.
- Members : به منظور اعمال ارتباط چند به چند بین مدل کاربر و مدل کلکسیون، در نظر گرفته شده است و زمانی این لیست اعضا خالی نیست که حالت Visibility با NotFree یا Custom مقدار دهی شده باشد.
- Tags : برای یافتن راحتتر کلکسیونهای مورد نظر کاربران، یک ارتباط چند به چند بین کلکسیونها و مخزن برچسب مطرح شدهی در مقاله اول، در نظر گرفته شده است.
- TagNames : برای افزایش کارآیی سیستم در نظر گرفته شده است و نام برچسبهای در ارتباط با کلکسیون را در خود به صورت جدا شده با (,) نگهداری میکند.
- Posts : لیست پستهایی است که توسط مدیر کلکسیون در آن ارسال میشود. لذا یک ارتباط یک به چند بین کلکسیونها و CollectionPost در نظر گرفته شده است.
- Attachments : لیست فایلهایی است که در کلکسیون بارگذاری شدهاند (در ادامه پیاده سازی خواهد شد).
- Owner , OwnerId : هر کلکسیون نیز یک صاحب خواهد داشت. بدین منظور یک ارتباط یک به چند بین کاربر و کلکسیون برقرار شده است.
- HowToPay : توضیحاتی در مورد نحوهی پرداخت هزینه (در صورتی که Visibility این کلکسیون NotFree باشد).
مدل پستهای کلکسیون ها
public class CollectionPost : GuidBaseEntity { #region Properties /// <summary> /// indicate this post should be pin /// </summary> public virtual bool IsPin { get; set; } /// <summary> /// gets or sets the blog pot body /// </summary> public virtual string Body { get; set; } /// <summary> /// gets or sets the content title /// </summary> public virtual string Title { get; set; } /// <summary> /// gets or sets value indicating Custom Slug /// </summary> public virtual string SlugAltUrl { get; set; } /// <summary> /// gets or sets a value indicating whether the content comments are allowed /// </summary> public virtual bool AllowComments { get; set; } /// <summary> /// indicate comments should be approved before display /// </summary> public virtual bool ModerateComments { get; set; } /// <summary> /// gets or sets viewed count /// </summary> public virtual long ViewCount { get; set; } /// <summary> /// Gets or sets the total number of approved comments /// <remarks>The same as if we run Item.Comments.Count() /// We use this property for performance optimization (no SQL command executed) /// </remarks> /// </summary> public virtual int ApprovedCommentsCount { get; set; } /// <summary> /// Gets or sets the total number of unapproved comments /// <remarks>The same as if we run Item.Comments.Count() /// We use this property for performance optimization (no SQL command executed) /// </remarks> /// </summary> public virtual int UnApprovedCommentsCount { get; set; } /// <summary> /// gets or sets rating complex instance /// </summary> public virtual Rating Rating { get; set; } /// <summary> /// gets or sets information of User-Agent /// </summary> public virtual string Agent { get; set; } /// <summary> /// indicate users can share this post /// </summary> public virtual bool IsEnableForShare { get; set; } #endregion #region NavigationProperties /// <summary> /// get or set comments of this post /// </summary> public virtual ICollection<CollectionComment> Comments { get; set; } /// <summary> /// gets or sets collection that associated with this post /// </summary> public virtual Collection Collection { get; set; } /// <summary> /// gets or sets id of collection that associated with this post /// </summary> public virtual Guid CollectionId { get; set; } #endregion }
- IsEnableForShare : اگر با مقدار True مقدار دهی شده باشد ، امکان به اشتراک گذاری آن درشبکههای اجتماعی وجود خواهد داشت.
- Comments : اگر مقدار AllowComments مربوط به پست ارسالی true باشد، در آن صورت امکان نظر دهی به پست هم امکان پذیر خواهد بود. برای برقراری ارتباط یک به چند بین مدل پست کلکسیون و نظرات کلکسیون، این لیست در مدل بالا گنجانده شده است.
- ModerateComments : اگر برای پست خاصی، با مقدار true مقدار دهی شده باشد، نظرات آن پست قبل از نمایش باید توسط مدیر آن کلکسیون تأیید شوند.
- Author , AuthorId : در واقع ارسال کنندهی تمام پستها، همان صاحب کلکسیون میباشد. ولی برای راحتی واکشی لیست پستهای ارسالی کاربر مورد نظر یک ارتباط یک به چند بین کاربر و پستهای ارسالی را در کلکسیون اعمال کردهایم.
- Collection , CollectionId : کلید خارجی ما در دیتابیس ایجاد شده خواهد بود که نشان دهندهی ارتباط یک به چند بین کلکسیون و پستها میباشد.
- IsPin : اگر لازم است پستی به عنوان اولین پست در کلکسیون نمایش داده شود، این خصوصیت برای آن true خواهد بود.
- ApprovedCommentsCount , UnApprovedCommentsCount: برای افزایش کارآیی سیستم در نظر گرفته شده است و هنگام درج نظر جدید یا حذف نظر، ویرایش خواهند شد.
مدل نظرات ارسالی در کلکسیون ها
public class CollectionComment { #region Ctor public CollectionComment() { Id = SequentialGuidGenerator.NewSequentialGuid(); CreatedOn = DateTime.Now; } #endregion #region Properties /// <summary> /// get or set identifier of record /// </summary> public virtual Guid Id { get; set; } /// <summary> /// gets or sets date of creation /// </summary> public virtual DateTime CreatedOn { get; set; } /// <summary> /// gets or sets body of blog post's comment /// </summary> public virtual string Body { get; set; } /// <summary> /// gets or sets body of blog post's comment /// </summary> public virtual Rating Rating { get; set; } /// <summary> /// gets or sets informations of agent /// </summary> public virtual string UserAgent { get; set; } /// <summary> /// indicate this comment is Approved /// </summary> public virtual bool IsApproved { get; set; } /// <summary> /// gets or sets Ip Address of Creator /// </summary> public virtual string CreatorIp { get; set; } /// <summary> /// gets or sets datetime that is modified /// </summary> public virtual DateTime? ModifiedOn { get; set; } /// <summary> /// gets or sets counter for report this comment /// </summary> public virtual int ReportsCount { get; set; } /// <summary> /// indicate this entity is Locked for Modify /// </summary> public virtual bool ModifyLocked { get; set; } /// <summary> /// gets or sets date that this entity repoted last time /// </summary> public virtual DateTime? ReportedOn { get; set; } #endregion #region NavigationProperties /// <summary> /// gets or sets post that this comment added it /// </summary> public virtual CollectionPost Post { get; set; } /// <summary> /// gets or sets id of post that this comment added it /// </summary> public virtual Guid PostId { get; set; } /// <summary> /// get or set user that create this record /// </summary> public virtual User Creator { get; set; } /// <summary> /// get or set Id of user that create this record /// </summary> public virtual long CreatorId { get; set; } /// <summary> /// gets or sets CollectionComment's identifier for Replying and impelemention self referencing /// </summary> public virtual Guid? ReplyId { get; set; } /// <summary> /// gets or sets Collection's comment for Replying and impelemention self referencing /// </summary> public virtual CollectionComment Reply { get; set; } /// <summary> /// get or set collection of Collection's comment for Replying and impelemention self referencing /// </summary> public virtual ICollection<CollectionComment> Children { get; set; } #endregion }
مدل بالا نشان دهندهی نظرات ارسالی برای پستهای کلکسیونها میباشد. صرفا کاربران عضو سیستم این اجازه را در صورتی خواهند داشت که برای پست مورد نظر خصوصیت AllowComments با مقدار true مقدار دهی شده باشد
حالت درختی آن مشخص است. برای اعمال ارتباط یک به چند بین پستها و نظرات، از CollectionPost و CollectionPostId استفاده خواهد شد.
- IsApproved : برای زمانی استفاده خواهد شد که خصوصیت ModerateComments پست مورد نظر با مقدار true مقدار دهی شده باشد.
- ReportsCount : به مانند بخشهای قبل، تعداد اخطارهای داده شدهی برای یک نظر را نشان خواهد داد.
- Creator,CreatorId : ارسال کنندهی نظر میباشد و برای ایجاد ارتباط یک به چند بین کاربر و نظرات کلکسیونها در نظر گرفته شدهاند.
- ReportedOn : نگه داری آخرین تاریخ اخطار
- ModifyLocked : به منظور ممانعت از ویرایش
مدل فایلهای ضمیمه کلکسیون ها
public class CollectionAttachment : BaseAttachment { #region NavigationProperties /// <summary> /// gets or sets Collection that this file attached /// </summary> public virtual Collection Collection { get; set; } /// <summary> /// gets or sets Id of Collection that this file attached /// </summary> public virtual Guid? CollectionId { get; set; } #endregion }
مدل آگهی ها
/// <summary> /// Represents Announcement For Announcement Section /// </summary> public class Announcement : BaseContent { #region Properties /// <summary> /// gets or sets Date that this Announcement will Expire /// </summary> public virtual DateTime? ExpireOn { get; set; } /// <summary> /// indicate this accouncement is approved by admin if announcementSetting.Moderate==true /// </summary> public virtual bool IsApproved { get; set; } #endregion #region NavigationProperties /// <summary> /// get or set Collection of Comments for this Announcement /// </summary> public virtual ICollection<AnnouncementComment> Comments { get; set; } #endregion }
- ExpireOn : زمان انقضای آگهی
- IsApproved : به منظور اعمال مدیریتی در نظر گرفته شده است
- Comments : اگر امکان ارسال نظرات برای آگهی از بخش تنظیمات فعال باشد، این لیست نظرات ما را نگه داری خواهد کرد. لذا یک رابطهی یک به چند بین نظرات و آگهیها خواهد بود.
مدل نظرات آگهی ها
/// <summary> /// Repersents Comment For Announcement /// </summary> public class AnnouncementComment : BaseComment { #region NavigationProperties /// <summary> /// gets or sets body of announcement's comment /// </summary> public virtual long? ReplyId { get; set; } /// <summary> /// gets or sets body of announcement's comment /// </summary> public virtual AnnouncementComment Reply { get; set; } /// <summary> /// gets or sets body of announcement's comment /// </summary> public virtual ICollection<AnnouncementComment> Children { get; set; } /// <summary> /// gets or sets announcement that this comment sent to it /// </summary> public virtual Announcement Announcement { get; set; } /// <summary> /// gets or sets announcement'Id that this comment sent to it /// </summary> public virtual long AnnouncementId { get; set; } #endregion }
مدل سیستم لاگ عملیات کاربران
/// <summary> /// Represent The Operation's log /// </summary> public class AuditLog { #region Ctor /// <summary> /// /// </summary> public AuditLog() { Id = SequentialGuidGenerator.NewSequentialGuid(); OperatedOn = DateTime.Now; } #endregion #region Properties /// <summary> /// sets or gets identifier of AuditLog /// </summary> public virtual Guid Id { get; set; } /// <summary> /// sets or gets description of Log /// </summary> public virtual string Description { get; set; } /// <summary> /// sets or gets when log is operated /// </summary> public virtual DateTime OperatedOn { get; set; } /// <summary> /// sets or gets log's section /// </summary> public virtual AuditSection Section { get; set; } #endregion #region NavigationProperties /// <summary> /// sets or gets log's creator /// </summary> public virtual User OperatedBy { get; set; } /// <summary> /// sets or gets identifier of log's creator /// </summary> public virtual long OperatedById { get; set; } #endregion } public enum AuditSection { Blog, News, Forum, ... }
مدل دامینهای ممنوع
/// <summary> /// Represents Domain that is banned /// </summary> public class BannedDomain { #region Propertie /// <summary> /// gets or sets identifier of Domain /// </summary> public virtual Guid Id { get; set; } /// <summary> /// gets or sets DomainName /// </summary> public virtual string Name { get; set; } /// <summary> /// gets or sets Date that this record added /// </summary> public virtual DateTime BannedOn { get; set; } #endregion }
مدل کلمات ممنوع
/// <summary> /// Represents the banned words /// </summary> public class BannedWord { #region Ctor /// <summary> /// Create one instance of <see cref="BannedWord"/> /// </summary> public BannedWord() { Id = SequentialGuidGenerator.NewSequentialGuid(); } #endregion #region Properties /// <summary> /// gets or sets identifier of BannedWord /// </summary> public Guid Id { get; set; } /// <summary> /// gets or sets Bad word /// </summary> public string BadWord { get; set; } /// <summary> /// gets or sets Good replaceword /// </summary> public string GoodWord { get; set; } /// <summary> /// indicating that this Word is spam /// </summary> public bool IsStopWord { get; set; } #endregion }
- BadWord : کلمه مورد نظر که قرار است Ban شود.
- IsStopWord : اگر لازم نیست جایگزینی برای کلمه استفاده شود و فقط لازم است حذف گردد، مقدار این خصوصیت true خواهد بود.
- GoodWord : کلمه جایگزین
مدل تنظیمات سیستم
/// <summary> /// Represent The CMS setting /// </summary> public class Setting { #region Properties /// <summary> /// sets or gets name of setting /// </summary> public virtual string Name { get; set; } /// <summary> /// sets or gets value of setting /// </summary> public virtual string Value { get; set; } /// <summary> /// sets or gets Type of setting /// </summary> public virtual string Type { get; set; } #endregion }
نتیجهی این قسمت
AngularJs و i18n
The new i18n story in Angular
Internationalization support in Angular has been very poor so far. You might know that there’s anngLocale
module you need to include, which is used by a couple components, likengPluralize
,date
andcurrency
filter to name a few, and that’s pretty much it. As we’ve already discussed, there’s so much more that comes into play when internationalizing an application, which is why there’s finally a new solution evolving that will bring first-class i18n support to the Angular framework.
برای آغاز به کار با این دیتابیس ابتدا باید آن را از سایت اصلی دریافت و بر روی سیستم نصب نمایید. متاسفانه سایت مونگو برای کشور ایران محدودیتی قرار داده است و باید از روشهای دیگری آن را دریافت نمایید و بر روی سیستم خود نصب نمایید. نحوه نصب این دیتابیس را میتوانید در مقاله MongoDb#3 مشاهده نمایید.
شاید نیاز باشد بجای کار کردن با محیط کنسول این دیتابیس، با یک محیط گرافیکی شبیه آن چیزی که Raven دارد کار کنید وتغییرات را مشاهده نمایید؛ برای همین به این آدرس رفته و محیط دلخواه خود را انتخاب نمایید.
یک پروژه از نوع کنسول را در ویژوال استادیو ایجاد کنید و سپس درایور رسمی مونگو را از این آدرس یا از طریق nuget نصب نمایید:
Install-Package mongocsharpdriver
ابتدا سه مدل را به شکل زیر ایجاد میکنیم:
public class Author { public ObjectId Id { get; set; } public string Name { get; set; } }
public class Language { public ObjectId Id { get; set; } public string Name { get; set; } }
public class Book { public ObjectId Id { get; set; } public string Title { get; set; } public string ISBN { get; set; } public int Price { get; set; } public List<Author> Authors { get; set; } public Language Language { get; set; } }
نوع ObjectId، نوعی است که توسط مونگو برای مشخص کردن کلید یکتای سند معرفی میشود.
در خطوط اولیه کد زیر، یک شیء از مدل بالا را ساخته و آن را مقداردهی میکنیم:
var book =new Book() { Title = "Gone With Wind", ISBN = "43442424", Price = 50000, Language = new Language() { Name = "Persian" }, Authors = new List<Author>() { new Author() { Name = "Margaret Mitchell" }, new Author() { Name = "Ali Mahboobi (Translator)" }, } };
بعد از آن یک شیء کلاینت از نوع mongoClient میسازیم که نوع خروجی آن یک اینترفیس میباشد که توسط کلاسی از جنس آن مقداردهی شده است. بیشتر خروجیهای مونگو در این کتابخانه از نوع اینترفیس هستند. شیء کلاینت وظیفه دارد تا ارتباط شما را با سرور مونگو برقرار کند:
var client = new MongoClient();
string connectionString = "mongodb://localhost:27017"; MongoClientSettings settings = MongoClientSettings.FromUrl(new MongoUrl(connectionString)); var client = new MongoClient(settings);
در قسمت بعد لازم است که از سرور جاری، دیتابیس خود را دریافت کنیم. در صورتیکه دیتابیس درخواستی وجود نداشته باشد، یک دیتابیس جدید با آن نام ساخته خواهد شد:
var db = client.GetDatabase("publisher");
در مونگو اصطلاحی به نام collection وجود دارد که اسناد در آن قرار گرفته و ارتباط با اسناد از طریق آنها انجام میپذیرد. پس در اینجا قبل از هر کاری باید یک collection را ایجاد کرد و در صورتیکه کالکشن درخواستی وجود نداشته باشد، آن را تولید و ارتباط با آن را برخواهد گرداند.
var collection = db.GetCollection<Book>("books");
در اینجا کالکشنی با نام books با تبدیلاتی بر اساس مدل Book ایجاد میشود. در مرحله بعد لازم است که شیء ایجاد شده بر اساس کلاس مدل را با استفاده از متدهای insert شیء کالکشن، در دیتابیس ارسال کنیم.
شیءهای درج یک سند جدید به دیتابیس حالات مختلفی را دارد: افزودن تک سند، افزودن چند سند و دو مورد قبلی به صورت غیر همزمان میباشند:
collection.InsertOneAsync(book);
فعلا موجودیتهای مؤلفان و زبان به دلیل اینکه سند اختصاصی برای خود ندارند، با صفر پر شدهاند؛ ولی شناسه یکتای سند، مقدار خود را گرفته است.
عملیات خواندن
قبل از هر چیزی برای اینکه در مانور دادن بر روی دادهها راحت باشیم و اطلاعات را با فیلترهای متفاوتی واکشی کنیم، 7 عدد کتاب را با مشخصات زیر اضافه میکنیم. دو فیلد سال و تاریخ آخرین موجودی انبار را هم اضافه میکنیم.
var client = new MongoClient(); var db = client.GetDatabase("publisher"); db.DropCollection("books"); var collection = db.GetCollection<Book>("books"); var book =new Book() { Title = "Gone With Wind", ISBN = "43442424", Price = 50000, Year = 1936, LastStock = DateTime.Now.AddDays(-13), Language = new Language() { Name = "Persian" }, Authors = new List<Author>() { new Author() { Name = "Margaret Mitchell" }, new Author() { Name = "Ali Mahboobi (Translator)" }, } }; var book2 = new Book() { Title = "Jane Eyre", ISBN = "87897897", Price = 60000, Year = 1847, LastStock = DateTime.Now.AddDays(-5), Language = new Language() { Name = "English" }, Authors = new List<Author>() { new Author() { Name = "Charlotte Brontë" }, } }; var book3 = new Book() { Title = "White Fang", ISBN = "43442424", Price = 50000, Year = 1936, LastStock = DateTime.Now.AddDays(-13), Language = new Language() { Name = "English" }, Authors = new List<Author>() { new Author() { Name = "Jack London" }, new Author() { Name = "Philippe Mignon" }, } }; var book4 = new Book() { Title = "The Lost Symbol", ISBN = "43442424", Price = 3500000, Year = 2009, LastStock = DateTime.Now.AddDays(-17), Language = new Language() { Name = "Persian" }, Authors = new List<Author>() { new Author() { Name = "Dan Brown" }, new Author() { Name = "Mehrdad" }, } }; var book7 = new Book() { Title = "The Lost Symbol", ISBN = "43442424", Price = 47000000, Year = 2009, LastStock = DateTime.Now.AddDays(-56), Language = new Language() { Name = "Persian" }, Authors = new List<Author>() { new Author() { Name = "Dan Brown" }, new Author() { Name = "Mehrdad" }, } }; var book5= new Book() { Title = "The Help", ISBN = "45345e3er3", Price = 9000000, Year = 2009, LastStock = DateTime.Now.AddDays(-2), Language = new Language() { Name = "Enlish" }, Authors = new List<Author>() { new Author() { Name = "Kathryn Stockett" }, } }; var book6 = new Book() { Title = "City of Glass", ISBN = "454534545", Price = 500000, Year = 2009, LastStock = DateTime.Now, Language = new Language() { Name = "Persian" }, Authors = new List<Author>() { new Author() { Name = "Cassandra Clare" }, new Author() { Name = "Ali" }, } }; var books = new List<Book> {book, book2, book3, book4, book5, book6,book7}; collection.InsertManyAsync(books);
برای واکشی دیتاها کالکشنی از آن نوع را همانند قبل درخواست میکنیم. بعد از آن نیاز است که فیلتری برای واکشی اطلاعات تعریف کنیم که این فیلتر در قالب یک کلاس به نام BsonDocument ایجاد میشود که ما در اینجا، به دلیل اینکه میخواهیم همه اسناد را واکشی کنیم ، این سند Bson را مقداردهی نمیکنیم و توسط متد Find آن را در واکشی دیتاها شرکت میدهیم و سپس با صدا زدن متد ToList، عملیات واکشی را انجام میدهیم، برای اینکار میتوانیم از عملیات غیرهمزمان هم استفاده کنیم.
var client = new MongoClient(); var db = client.GetDatabase("publisher"); var collection = db.GetCollection<Book>("books"); var filter=new BsonDocument(); var docs = collection.Find(filter).ToList(); foreach (var book in docs) { Console.WriteLine(book.Title + " By "+ book.Authors[0].Name); }
با اجرای کد بالا به نتایج زیر میرسیم:
Gone With Wind By Margaret Mitchell Jane Eyre By Charlotte Brontë White Fang By Jack London The Lost Symbol By Dan Brown The Help By Kathryn Stockett City of Glass By Cassandra Clare The Lost Symbol By Dan Brown
اگر بخواهید فیلتری را بر روی این واکشی قرار دهید و مثلا بخواهید کتابهای منتشر شده در سال 2009 را واکشی نمایید، باید این سند Bson را مقداردهی نمایید. ولی برای راحتی اینکار، این کتابخانه شامل یک بیلدر Builder بوده که میتوان از طریق آن فیلترهای متنوعی را به صورت سادهتر طراحی کنید:
در خطوط بالا ابتدا یک بیلدر را برای کلاس مورد نظر ایجاد کرده و از خصوصیت Filter آن استفاده میکنیم و این خصوصیت شامل متدهای فراوانی است که میتوانید برای ایجاد شرط یا فیلتر استفاده کنید. تعدادی از متدهای پر استفاده آن همانند eq (برابری) ، gt (برزگتر از ...) ، gte (بزرگتر مساوی ...) و طبیعتا خانواده lt و ... موجود هستند.
var filter = Builders<Book>.Filter.Eq("Year", 2009); var docs = collection.Find(filter).ToList(); foreach (var book in docs) { Console.WriteLine(book.Title + " By "+ book.Authors[0].Name); }
The Lost Symbol By Dan Brown The Help By Kathryn Stockett City of Glass By Cassandra Clare The Lost Symbol By Dan Brown
// var filter=new BsonDocument(); var filterBuilder = Builders<Book>.Filter; var filter= filterBuilder.Eq("Year", 2009) | filterBuilder.Gte("Price",700000); var docs = collection.Find(filter).ToList(); foreach (var book in docs) { Console.WriteLine(book.Title + " By "+ book.Authors[0].Name); }
Gone With Wind By Margaret Mitchell White Fang By Jack London The Lost Symbol By Dan Brown The Help By Kathryn Stockett City of Glass By Cassandra Clare The Lost Symbol By Dan Brown
برای اینکه بتوانید از linq به جای queryBuilder استفاده کنید، میتوانید از خصوصیت AsQueryable استفاده کنید. خط زیر همان شرط یا فیلتر بالا را توسط Linq اعمال میکند
var docs = collection.AsQueryable().Where(x => x.Year == 2009 || x.Price <= 50000).ToList();
Sort کردن دادهها
برای مرتب سازی اطلاعات به شیوه کوئری بیلدر، همانند فیلتر که از کلاس Builder استفاده میکردیم، از همین شیء استفاده میکنیم؛ با این تفاوت که بجای استفاده از خصوصیت Filter، از Sort استفاده میکنیم و شیء ایجاد شده را به متد Sort میدهیم:
var sort = Builders<Book>.Sort.Ascending("Title").Descending("Price"); var docs = collection.Find(filter).Sort(sort).ToList(); foreach (var book in docs) { Console.WriteLine(book.Title + " By "+ book.Authors[0].Name); }
City of Glass By Cassandra Clare Gone With Wind By Margaret Mitchell The Help By Kathryn Stockett The Lost Symbol By Dan Brown The Lost Symbol By Dan Brown White Fang By Jack London
توجه داشته باشید که متد sort بعد از فیلتر گذاری، یعنی عمل Find در دسترس میباشد.
در قسمت بعدی به روزرسانی، حذف و ایندکس گذاری را مورد بررسی قرار میدهیم.
سری بررسی پشت صحنهی دات نت
In this series I answer various .NET questions. Some of them are asked during interviews, some of them I see on the internet, some of them are completely made up. The goal is to provide short answer with links to references if needed. This is by no means a .NET tutorial or experts reference, this is just a bunch of useful answers to refresh your knowledge.