متن صدای ویدیو :

دوستان من تو این ویدئو می خواهم راجع به جداول صحبت کنم، اما قبل از جداول من باید چند تا نکته را توضیح بدم. اولین نکته راجع به ذخیره اطلاعات به ساختار Tree هست، ما تو پلتفرم خیلی از ساختار Tree استفاده کردیم، یه سری جداول را با ساختار Tree انجام می دهیم، جدول MasterData، جدول Link، جدول Comment.

خب ساختار Tree خیلی مزیت داره، هم تو نمایش به User خیلی خوبه هم تو ذخیره دیتا. اگر شما لینک ها را نگاه کنید تا n Level در اصل میتونیم پیشروی داشته باشیم و اطلاعات را به شکل خوبی به User هامون نشون بدیم. و اساسا شما  اطلاعات را نگاه کنید، خیلی از اطلاعات قابلیت ذخیره شدن به ساختار Tree را دارن، منتهی مشکل از آنجاست که Entity Framework و Linq to Entity  با ساختار Tree  زیاد میانه خوبی ندارن، یعنی فرض کنید که شما از یک ساختار درختی یا Tree که دارید، می خواهید مثلا تو Level سوم یکی از node ها تمام child هاش تا nLevel بچه هاش تا nLevel node ها بچه ی اون Parent با یک کوئری select کنید بیارید نمونه اش همین منو سمت چپ دسترسی های کاربری هست که وارد میشه، میبینید که یه Tree است که تا nLevel میاد و این وسط خود Tree لینک هاست.

یعنی یک قسمت وسط این Tree دسترسی های کاربر جاریه، اگه بخواهیم این را با Linq to Entity  بنویسیم، یا غیر ممکنه یا خیلی مشکله چون شما اون موقعه باید ساختار جدول تون را طوری باید بگیرید که اونchild nLevel  هم به اون Parent اصلی که حالا شما مد نظر تون هست را دسترسی داشته باشته، یعنی یک field ها را تو جدول بگیرید که این child ها به  تک تک Parent های بالا سرشون ربط داشته باشه. خب این موقعه update یا insert یک حجم عظیمی از تغییرات تو Database تون می خواهد که اصلا یک چیز خیلی وحشتناکی میشه. برای حل این مشکل حتما یا باید از Stored Procedure استفاده کنیم یا این که نه اگر حتما می خواهید از Entity  framework استفاده کنیم.

ما یک گزینه ای گذاشتیم برای شما تو قسمت مدیریت محتوا، مدیریت گروه ها، ما دو تا از جداول مهم که ساختارشون Treeهست ، یکی MasterData و یکی Link ها یعنی MasterdataKeyValue و Link مون را قابلیت گروه کردن اطلاعاتشو را داریم، یعنی وقتی پلتفرم نصب میشه یک گروه پیشفرض بیشتر نداریم اون هم لینک های دسترسی کاربر جاریه که همین منو این جاست، یعنی این منو به کمک این گروه Link های دسترسی کاربر جاری میاد که حالا من query  ش را هم به شما نشون میدم.

این گروه Link های دسترسی کاربر جاری را که انتخاب کنیم، می بینید که از وسط این Link ها اومده تو بخش مدیریت، برداشته یک سری شون را آورده، شما باید تک تک منو هایی را که می خواهید ، با Parent شون انتخاب کنید تا توی آن query  نهایی شما این گروه نمایش داده بشه.

هر لینکی که می خواهید خودش و پدرش را باید انتخاب کنید. خود تنهاش یا پدر تنهاش فایده ای نداره، خودش و پدرش را باید انتخاب کنید و پدرانش را تا برسه به node پدر اصلی، همه را دونه دونه تک تک انتخاب بکنید تا اون برای شما نمایش داده بشه، گروه کردن را هم گفتم روی دو تا جدول MasterData و Link. که تو MasterData ، نوع اطلاعات پایه را هم مشخص کنید مثلا روی عملیات ها  و بعد بیاید روی عملیات ها، و مثلا" از روی عملیات ها برای خودتون یک گروه بسازید.  این query  شو هم چطوری استفاده میشه هم تو سرویس های odata باشه هم تو سرویس های HTTP. که حالا من یک دونه odata برای شما نشون میدم.

تو سرویس های مدیریت محتوا، سرویس مدیریت Link ها، سرویس های odata Link ها، دسترسی های کاربر جاری،  می بینید که اولا اسم جدولش هست Entity Gorups و اومده گفته که Entity type Id ش مساوی 101 باشه، 101 منظور Entity از نوع Link هست.من الان این را جلوتر براتون توضیح میدم، و Group Id ش 71  هم که همون گروه مدیریت دسترسی کاربر جاری هست و Language را هم می توانید set کنید. توی URL نهایی که ما ساختیم ، اومدیم اون Language را پارامتریک کردیم، @lang ش کردیم و Group Id  71 ثابته و Entity type Id  101 ثابته  ، برای query  دسترسی های کاربر جاری.

 اما اون 101 که میخواستم توضیح بدم Entity type Id ، ما اگه بیایم توی source بیایم توی KS.Core توی قسمت GlobalVarioable تو قسمت enumeration  ما یک enum داریم به اسم EntityIdentity که آیدی ها تمام موجودیت های ما، چه واقعی چه مجازی، اینجا هست، واقعی ها مانند جدول Link یا مدل Link که جدول فیزیکی داره با رنج 100 شروع میشه مثلا Link  هست101، مجازی ها، مثل service که توی MasterData تعریف شدن تو همون جدول MasterData ذخیره می شوند و جدول جداگانه ندارن اما موجودیت جداگانه ای حساب میشن با هزاراند ، تو رنج هزار تعریف شدند  مثلا 1001 ، Entity سرویس و از این Entity ها شما هم می توانید توی کد تون  استفاده کنید. برای اینکه بدانید مثلا همین گروه ها برای کدام Entity برای  Link هست یا MasterData است. اگه MasterData است برای کدام Entity هست و Entity type Id اش چیه.

نکته دوم که می خواهیم توضیح بدم راجع به یه آپشن دیگه ای که ما داریم. ما قبلا مدیریت فایل سیستم را توضیح دادیم، که میاد روی دیسک و فایل های فیزیکی ما که روی دیسک هستن را نشون میدن، غیر از مدیریت فایل ها، ما یک مدیریت فایل ها و میسرها داریم که توی مدیریت محتوا، مدیریت فایل ها و مسیر ها خودش  دو قسمته، مدیریت مسیر ها و مدیریت فایل ها ، من مدیریت مسیرها را انتخاب می کنم.

اولا باید بگم که نوع فایلش از چه نوعیه و مسیر فیزیکش کجاست. ما تو قسمت مدیریت مسیر ها می توانیم یک سری از مسیرها را توی دیتابیس ذخیره کنیم. کدام مسیرها را؟ ببینید ما توی طراحی وبسایت تو سمت client توی CSS، HTML، JavaScript می توانیم خیلی از عکس ها و فایل ها استفاده کنیم، که اینها حتما نیازی نداره که حتما توی دیتابیس هم مشخص باشه، اما یک سری از فایل های ما مثل همین پرچم ها، پرچم کانادا، ایران و استرالیا که توquery  ما تو سمت سرور نوشته میشه، ما نیاز داریم که توی دیتابیس وجود داشته باشه تا ما بتوانیم روش کوئری  بزنیم.

بنابراین ما به جای اینکه خود فایل را ذخیره کنیم که حجم بیشتری بگیره، فایل را روی دیسک گذاشتیم و مسیرش را آمدیم توی جدول مسیرهامون ذخیره اش کردیم. از این مسیرها حالا هم میتونیم توی جداول دیگر تو مدل های دیگه به عنوان child استفاده کنیم. همین اینکه فقط توی  همین این جدول باشه و بتوانیم روش query بزنیم و به کاربرمون نشون بدیم. پس این راجع به مدیریت مسیرها که جدولش هم هست،جدول Filepath که در اسکیمای ContentManagement.

 اما مدیریت فایل ها، مدیریت فایل ها هم باز دقیقا عین همون مدیریت مسیرهاست منتهی این دفعه ما به جای اینکه فقط آن مسیر فایل را ذخیره کنیم خود فایل را هم توی دیتابیس ذخیره می کنیم.

در اصل شما مثلا  اول مسیر فیزیکی را مشخص می کنید بعد میتونید اون فایل را روی دیتابیس ذخیره کنید. و اگه خواستید بعدش فایل را از روی دیسک حذفش کنید. بعد می توانید روشquery  بزنید دوباره بگید که این فایل تو این مسیر فیزیکی بوده و از نوع تصویر بوده را به من نشان بده و بعد از روی دیتابیس برای شما بیاره.

در اصل قابلیت ذخیره فایل ها روی دیتابیس که بعنوان یک Sample برای شما هست که میتونید حالا یا از همین استفاده کنید توی وبسایت خودتون یا از روی این برای User هاتون اگه خواستند فایل آپلود کنند و شما فایل را در دیتابیس ذخیره کنید از این ایده بگیرید.

جدولش هم جدول فایل هست، ما غیر از جدول file و filepath دو تا جدول دیگه هم داریم یکی EntityFiles و یکی EntityFilePaths و یک جدول دیگه Entity MasterDatakeyValues که اون هم شبیه این دو تا جدول است.

EntityFiles و EntityFilePaths به این معنی هست که هر جدول یا مدل دیگه تو Entity framework ، می خواهد که یه لیستی از file یا filepath داشته باشه ، به جای اینکه مستقیما به این جداول تو مدل وصل باشه ، لیستی از EntityFilePaths و EntityFiles داره و همین طور MasterDatakeyValues حالا اگر هر مدلی بخواهد یه لیستی از MasterDatakeyValues ها را داشته باشه ، یه لیستی از EntityMasterDatakeyValues را داره ، من حالا این را توی مدل بیشتر توضیح میدم.

اولا من یه نکته بگم ما تو source علاوه بر KS. Model که مدل اجرایی هست ، یک مدل هم داریم ، به اسم KS.ObjectiveModel و یک لایه هم داریم به اسم KS.ObjectiveDataAccess ، این دوتا لایه برای آموزش Entity Framework هست و Object Orient  بودن مدل ، مدلی که به صورت Objective  تعریف میشه ، حالا شاید بگین خود EF که اصلا آمده Objective  کنه کار را ، منتهی این مدل اصلی ما یک مقدار Dynamic تره ، برای اینکه حالت CMS داره ، ولی برای وب سایت های معمولی که حالت Dynamic و CMS ندارن بهتره که از حالت Objective استفاده بشه ، ما جفت مدل ها را گذاشتیم توی source که شما بتونید هر دو مدل را ببینید ، مزایا و معایب اش را با هم مقایسه کنید و حالا هر نوعی که راحت تر بودین را انتخاب کنین . مزیت Dynamic این است که مدل Dynamic ، Dynamic تر است تو Run time و خب دستتون باز تره ، Objective  این است که خب Document  اش بهتره ، فهم مدل آسان تره. حالا من انشاء الله توی ویدئو های source اینها را بیشتر توضیح میدم.

برگردیم به مدل خودمون ما تو EntityFile و EntityFilePath ، من چون خیلی شبیه هم اند ، یکیشون را توضیح میدم و اون دومی هم دقیقا همین جوری هست ، اولا که ما دو تا مدل اصلی و واقعی مون ، Link و Webpage ، من الان داخل Webpage برم ، میتونن لیستی از file یا لیستی از FilePath ها داشته باشن که همین جوری هم که میبینید ، لیستی از EntityFilePath یا EntityFile ، غیر از دوتا مدل اصلیمون ، ما Entity های مجازی مون هم مثل سرویس ، یادتون باشه گفتم دیگه Entity واقعی مثل Link ، Entity مجازی که تو همون جدول MasterData ذخیره میشن مثل Service ، ما Entity های مجازی مون هم می تونن ، لیستی از فایل داشته باشن یا لیستی از EntityFile، برای این کار دوتا field دیگه داریم ، یکی Dynamic Entity type Id و Dynamic Entity type ، این دوتا اشاره میکنند به آن Entity که توی جدول MasterData ذخیره شده ، و یک دانه هم Entity type Id داریم که Id اون Entity هست دیگه، حالا چه مجازی و چه واقعی ، مثلا برای Link میشه 101 ولی اگر Entity مون مجازی باشه مثل سرویس ، Entity type Id مون میشه 1001، این دقیقا FilePath هم به همین شکل هست ، اما EntityMasterDataKeyValue فرق داره،  EntityMasterDataKeyValue  چون روی خود جدول MasterDataKeyValue هست ، دیگه عملا روی Entity مجازی این دسترسی را دادن یک مقداری غیر منطقی بود چون اصلا خود MasterData ، child Parent ، حالت Tree و حالا اگر بخواهد بچه داشته باشه خودش میتونه این کار را داشته باشه ، دیگه نیازی نداره اینجا مجدد تعریف بشه. بنابراین ما فقط اومدیم اینجا روی جداول Link،  file ،  FilePath و User ، یعنی ما مثلا ما  اگه توی جدول file امون بریم تو مدل file ، میبینید که مدل file میتونه یه لیستی از keyValue  ها را داشته باشه که از نوع EntityMasterDataKeyValue هست ، پس اینهم از توضیح این جداول .

خب من می خواهم تو این قسمت ، جداول هم توضیح بدم ، ما کلا دو تا اسکیما داریم وقتی که پلتفرم را نصب میکنیم ، به طور پیش فرض ، یکیContent Management ، یکی هم اسکیما های Security ، این اسکیما Dynamic که اینجا می بینید مال ویدئو های قبلی هست که ما داشتیم Entity Framework Migration  را آموزش میدادیم ، اومدیم اسکیما Dynamic و یه مدل هم به اسم Dynamic test model  ساختیم ، پس این مربوط به پلتفرم نیست ، برای آموزش هست ، اما تو اسکیما ContentManagement  ، جدول comment، این جدول comment فقط ساختار اش هست ، کدی براش زده نشده ، ایده اش هم این است که ما همه صفحات امون بتونه یه بخش comment داشته باشه که حالا یا روشن باشه یا خاموش و comment ها بیان توی جدول comment به صورت ساختار Tree ذخیره بشن ، یعنی commentی که زده میشه و یک comment در جواب اون comment ، دوباره اون comment جواب خودش میتونه یه جواب دیگه داشته باشه از طرف یک User دیگه ای ، به صورت سلسله مراتبی توی comment ذخیره شن ، ولی میگم توی ورژن یک استفاده خاصی ازش نشده ، کد براش وجود نداره .

EntityFilePath و EntityFile هم که توضیح دادم اینها دقیقا فقط ایده هستن توی ورژن یک ، کدی براشون زده نشده ، وجود دارند که حالا برنامه نویس ها یا از اینها ایده بگیرند ازشون استفاده کنن یا مثلا برای خودشون حالا جداول جدایی در نظر بگیرن ،  EntityGroupرا که توضیح دادم ، برای گروه کردن Tree هاست که ما بتونیم یک بخشی از وسط یک Tree را با همه ی Child های Parent بتونیم query  بزنیم در بیاریم که حالا روی جدول Link و MasterData ی ما براش کد نوشته شده و با هم دیدیم . EntityMasterDataKeyValue هم باز ازش استفاده خاصی نشده ، باز به صورت ایده هست ، تو مدل براتون توضیح دادم ، جدول FilePath و File هم باز اینها هم جدول File که استفاده نشده ولی FilePath استفاده شده ، توضیح اش را هم دادم که File برای Upload File هاست و FilePath هم که برای ذخیره مسیر هاست ، جدول language and cultures که جدول زبان ها و فرهنگ ماست که تو این ذخیره میشه ، جدول Link که جدول Link هامون هست و FilePath Local که هرجا که ما کلمه ی Local را دیدیم ترجمه جدول اصلی هست ، جدول اصلیش FilePath هست که با زبان پیش فرض ، زبان پیش فرضی که در وبکانفیگ، set شده توش رکورد ها ذخیره میشه و Local اش حالا به زبان های دیگه است ، شما n تا زبان میتونید تعریف کنید، عربی ، انگلیسی ، فرانسوی ، ترجمه ها میاد داخل این. Files Local هم باز همین جور ، ترجمه جدول File هست ، MasterDatakeyValue جدول اطلاعات پایه امون هست ، MasterDataLocalKeyValue جدول ترجمه اطلاعات پایه است.

اما جدول User، ببینید ما وقتی که User ثبت نام میکنه توی ASPNetUser  یه auto Identity  ای براش  Generate میشه ، همون Id موقع ثبت نام میاد توی جدول User هم به عنوان Id جدول User هم ثبت میشه ، یعنی Id این ، auto Identity نیست و از همون Id ،  ASP.NET Identity میاد . خود این جدول ASPNetUser  فیلد های زیادی داره ، نام و نام خانوادگی و نام پدر و ایمیل ، ولی اگر فیلدی برای شما وجود نداشت ، مثلا من اومدم توی ContentManagement تو جدول User ، فیلد AliasName اضافه کردم ، چرا ؟

چون گفتم اگر User بخواهد یه Commentی بگذاره با این نام مستعار اون Comment ، Username  اش نباشه یا نام و نام خانوادگی اصلیش نباشه ، یک AliasName باشه که User بتونه با اون مثلا Comment بگذاره . شما هم همین جور وقتی اسکیما خودتون را میسازید به اصطلاح این اسکیما سایت شما باشه ، جدول User اتون را میسازید ، هر فیلدی که دیدین توی جدول ASPNetUser  نیست تو جدول User خودتون add  میکنید. مثلا مثل AliasName. فقط Id ش را auto Identity نمیگذارین و موقع ثبت نام که حال سورس کد صفحه ثبت نام User هم هست می تونید ببینید ، بعد از اینکه Id این  generateشد همون Id را میارین توی جدول User خودتون بعنوان Id میگیرین. پس این جدول User هم میتونه یک Sample خوبی باشه برای شما که بتونید اسکیما وب سایت خودتون را که میسازین ، User اش را مرتبط کنید با قسمت Security.

و جدول Web page هم که جدول صفحات شماست دیگه ، بعد اسکیما Security جدول ApplicationQueryAuthorize که این فقط ساختار اش هست و ایده اش استفاده نشده توی کد ، یادتون باشه من گفتم که Odata  ی ما یک OData امنی هست با استفاده از اینکه هر رکوردی نقش دسترسی ، نقش دیده شدن داره ، اینکه چه کسی بتونه این رکورد را ببینه ، ولی یک وقتی هست که شما بیشتر از یک رکورد اصلا می خواهین برین تو قسمت فیلد ها اینکه چه کسی بتونه این فیلد را ببینه نه تنها در سطح رکورد ، یا حتی از اون ریزتر چه مقادیری از یک فیلد را ببینه اون موقع دیگه باید از یک چارچوب و ساختاری استفاده کنید که query  هاتون را Authorize کنید ، این جدول هم برای ایده هست ، استفاده نشده ازش ، شما میتونید چارچوب اش را ببینید ، من بعدا توی ویدئو های source بیشتر راجب OData که چجوری میشه مثلا از این جدول کجا باید استفاده کرد و کی باید Authorize کرد اونquery  های OData را تو ویدئو های source توی آینده انشاءالله بیشتر توضیح میدم ، ولی تو این ورژن یک از این جدول استفاده نشده و ایده است.

بعد جداول خود ASP.NET ، Users ASP.NET که گفتم فیلد های User ، ASP.UserRole نقش های User هست ASP.Userlogin و UserClaim برای کارهای داخلی  ASP.NET هست ،ASP.NETUsergroup ، جدول گروه های User ، ASPNETRoles  جدول roles هاست و ASP.NETLocalRoles ، در اصل ترجمه نقش های ASP.NETRoles هست ، ASP.NETLocalGroup  و ASP.NETGroups ، LocalGroup باز ترجمه گروه ها هست ، ASP.NETGroup به زبان پیش فرض هست و ASP.NETLocalGroup  با سایر زبان ها ، گروه ها ترجمه شدن توش ، ASP.NETGroupRoles  جدول نقش گروه هاست در اصل هر گروهی چه نقش هایی داره .

این هم توضیح جداول بود که ان شاالله توی ویدئو های بعدی بتونیم بیشتر توضیح بدیم.