<?xml version="1.0"?> <Configuration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <AllowAnonymousPush>false</AllowAnonymousPush> <Repositories>D:\GitRepo</Repositories> <AllowUserRepositoryCreation>true</AllowUserRepositoryCreation> <AllowAnonymousRegistration>false</AllowAnonymousRegistration> <DefaultLanguage>en-US</DefaultLanguage> <IsCommitAuthorAvatarVisible>true</IsCommitAuthorAvatarVisible> </Configuration>
قابلیت جالبی که در اینجا به نظر من خیلی مهم بود، استخراج تاریخچهی کامل ساب ورژن توسط گیت و انتقال همه آنها به مخزن گیت است که تنها با یک خط فرمان انجام پذیر است. برای اینکار مخرنی را در گیت ساخته و آدرس .git آن را برای اجرای فرمان نگه میداریم:
البته نصب گیت برای ویندوز برای صدور فرمان انتقال به گیت الزامی است که میتوانید از این آدرس آنرا دانلود و نصب کنید.
پس از آن در 2 مرحله مخرن ساب ورژن را به گیت انتقال میدهیم:
1- استخراج آن در یک مخزن لوکال
2- افزودن به سرور گیت (که راه اندازی شده)
برای استخراج مخزنی از ساب ورژن به یک مخزن لوکال گیت، یک فولدر خالی را ایجاد میکنیم. سپس با خط فرمان به آن وارد میشویم و بعد فرمان زیر را اجرا میکنیم:
در ادامه نام کاربری و کلمهی عبور را وارد میکنیم. البته به صورت پیش فرض، نام کاربری جاری ویندوز را در نظر میگیرد و بعد نام کاربری و کلمهی عبور سرویس ساب ورژن را میپرسد و حالا گیت کارش را شروع میکند:
پس از اتمام کار با توجه به مقالهی «مراحل ارسال یک پروژهی Visual Studio به GitHub» برای کار با گیت در ویژوال استودیو، میتوان به کار با گیت بصورت ریموت ادامه دهید.
و اما نکتهی آخر: من برای استفاده از این سرور مجبور بودم که نام localhost را با نام mehdi-pc جابجا کنم تا بتوانم از طریق یک کامپیوتر دیگر با سورس کنترل کار کنم و طی جستجوهایی که در اینترنت کردم، این کار بصورت کامند و فرمانهای شبه لینوکسی انجام پذیر بود. ولی راهی را همچون این مقاله «مشکل در جابجایی پروژههای svn» پیدا کردم که بنظرم آنرا مرتبط با موضوع میدانم و گفتن آن را خالی از لطف نمیبینم.
فایل config در واقع فایل کانفیگ داخل مخزن لوکال است؛ یعنی داخل فولدر .git و بصورت متنی ذخیره شده است:
طبق انتظار قسمتی از فایل که در زیر آمده، مربوط به مشخصات اتصال به سرور ریموت میباشد:
[remote "origin"] url = http://mehdi-pc:8551/NewsService.git fetch = +refs/heads/*:refs/remotes/origin/*
البته باید بسیار با دقت این تغییر را ایجاد کنید و مطمئن باشید که آدرس را بطور صحیح و به یک مخزن درست گیت تغییر میدهید.
- فایل ReadMe را فراموش نکنید
حتی اگر پروژه شما از یک سایت اختصاصی استفاده میکند، اولین محلی که عموم کاربران برای دریافت اطلاعات کار با پروژه، به آن مراجعه میکنند، فایل ReadMe برنامه است. این فایل میتواند حاوی مشخصات ذیل باشد:
الف) وابستگیهای پروژه را مشخص کنید
واقعیت این است که برخلاف شمای برنامه نویس، عموم استفاده کنندگان، آشنایی چندانی با جزئیات محیط و شرایط تهیه برنامه شما ندارند. به این ترتیب بسیاری از مسایلی که برای شما بدیهی هستند، برای عموم اینگونه نخواهند بود. بنابراین مسالهای که به سرعت میتواند سبب خشم کاربران و صرفنظر از کار شما گردد، مشخص نبودن نحوه نصب و وابستگیهای لازم برای اجرای برنامه است.
ب) وضعیت بلوغ پروژه خود را مشخص کنید
آیا از این برنامه، مدتی است که در محیط کاری استفاده میکنید؟ آیا به نظر شما هنوز ناتمام است؟ آیا API کتابخانه شما در نگارش بعدی کاملا دگرگون خواهد شد؟ تمام این مسایل و سؤالات را به نحو واضحی توضیح دهید و مشخص کنید. همین توضیحات کوتاه میتوانند ساعتهای بسیاری از زندگی دیگران را صرفه جویی کند.
ج) اگر پروژه شما یک کتابخانه است، نوع زبان و Runtimeهای پشتیبانی شده را مشخص کنید
برای مثال اگر یک کتابخانه دات نتی را ارائه میدهید، مشخص کنید که از کدام نگارش دات نت به بعد را پشتیبانی میکنید.
د) مجوز استفاده از پروژه را مشخص کنید
مطلب مقایسه مجوزهای سورس باز را یکبار مطالعه نمائید و سپس مجوز صحیحی را برای کار خود انتخاب کنید. همچنین آنرا به نحو واضحی در مستندات پروژه خود قید نمائید.
به علاوه بهخاطر داشته باشید که امکان ارائه مجوزهای دوگانه مانند AGPL نیز وجود دارند. در این حالت کاربر یا باید سورس محصول خودش را ارائه دهد، یا مجوز کتابخانه شما را خریداری کند. مانند RavenDB که از این نوع مجوز استفاده میکند.
- یک پروژه نیاز به مستندات دارد
مستند سازی کار، سخت و زمانبر است؛ اما بهترین لطفی است که میتوانید به کاربران خود نمائید. مستندات نه تنها زمان جستجوی بسیاری را صرفه جویی خواهند کرد، همچنین حس اطمینان خاطر را به کاربر القاء میکنند. از این جهت که احساس میکنند شما برای کارتان ارزش قائل بودهاید و احتمال اینکه این برنامه در آینده نزدیک به یک abandonware تبدیل شود، کم است (منظور یک برنامه فراموش شده و خاتمه یافته).
- به روز رسانی را ساده کنید
بالاخره زمانی نیاز خواهد بود تا نگارش جدیدی از کار خود را ارائه دهید. در این حالت نیاز است یک سری از شرایط را مدنظر داشته باشید:
الف) سازگاری قبلی را مدنظر داشته باشید
یکی از بدترین حالات به روز رسانی یک کتابخانه زمانی است که کاربر آن با دهها خطای کامپایل حاصل از به روز رسانی مواجه شود. اگر نیاز است قسمتی از کد خود را حذف کنید یا تغییر دهید، استفاده از ویژگی Obsolete را فراموش نکنید و اینکار باید مرحله به مرحله انجام شود. در یک نگارش، ویژگی Obsolete را معرفی کنید. در دو نگارش بعد، API را تغییر دهید.
ب) حتما یک Change log را تکمیل کنید
پس از ارائه یک نگارش جدید، حداقل در چند سطر مشخص کنید که چه مواردی تغییر کردهاند، چه مواردی اضافه شدهاند و چه مواردی را حذف کردهاید.
همچنین اگر مواردی تغییر کردهاند، نحوه ارتقاء کدهای قدیمی را به نگارش جدید، شرح دهید. اگر مورد جدیدی اضافه شدهاست، لینکی را به مثالی دربارهی آن ارائه دهید.
- نگارشهای جدید را اعلام کنید
برای مثال در طی ارائه یک مطلب جدید در وبلاگ خود، ارائه نگارش جدیدی از کتابخانه یا برنامه خود را به عموم اعلام کنید. در این حالت، حتما لینکی را به change log، ارائه داده و مشخص کنید که وضعیت سازگاری آن با قبل چگونه است.
- محلی را برای دریافت بازخوردهای پروژه خود مشخص کنید
نیاز است بتوانید پروژه خود را پشتیبانی کنید یا به سؤالات مربوطه پاسخ دهید. اگر سورس کنترل یا برنامه مدیریت پروژه شما، امکان پرسش و پاسخ را دارد، که بسیار خوب. اگر خیر، میتوانید مثلا یک گروه گوگل جدید و امثال آنرا برای دریافت بازخوردهای پروژه ایجاد کنید.
همچنین نیاز است لینک به این محل را در فایل ReadME پروژه به صراحت مشخص کنید.
- گذر از پروژه
بالاخره روزی فراخواهد رسید که دیگر علاقهای به نگهداری پروژه نداشته باشید. این مساله را در مکان جمع آوری بازخوردهای خود اعلام کنید یا شخص دیگری را به نگهداری پروژه دعوت نمائید. اگر این کار را انجام ندهید، سبب خواهید شد forkهای متعددی از این پروژه بیجهت ایجاد شده و در نهایت مشخص نباشد که کدامیک بهتر است و کدامیک مشکلات کمتری دارند.
using System.Web; namespace Intellisense.Models { public class Persons { // کلید public int Id { get; set; } // نام public string FirstName { get; set; } // نام خانوادگی public string LastName { get; set; } // نام پدر public string FatherName { get; set; } // سن public int Age { get; set; } // شماره تلفن public int Mobile { get; set; } // آدرس public string Address { get; set; } } }
using System.Collections.Generic; using System.Web.Mvc; using Intellisense.Models; namespace Intellisense.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { // List of person var listOfPerson = new List<Persons> { new Persons() {Id = 1, FirstName = "Jone", LastName = "liy", FatherName = "Sobin", Age = 36, Mobile = +982015222, Address = "..."}, new Persons() {Id = 2, FirstName = "kety", LastName = "sory", FatherName = "petter", Age = 19, Mobile = +962222155, Address = "..."}, }; // Set ViewBag.Persons data from listOfPerson ViewBag.Persons = listOfPerson; // Show and send ViewBag.Persons to view return View(); } } }
- استفاده از دات ( . )
- عمل Cast
@{ ViewBag.Title = "ViewBag"; } <table> <thead> <tr> <th> Id </th> <th> First Name </th> <th> Last Name </th> <th> Father Name </th> <th> Age </th> <th> Mobile </th> <th> Address </th> </tr> </thead> <tbody> @{foreach (var item in ViewBag.Persons) { <tr> <td> @item.Id </td> <td> @item.FirstName </td> <td> @item.LastName </td> <td> @item.FatherName </td> <td> @item.Age </td> <td> @item.Mobile </td> <td> @item.Address </td> </tr> } } </tbody> </table>
@using Intellisense.Models @{ ViewBag.Title = "ViewBag"; // روش اول // پیشنهاد میشود که از روش اول استفاده شود // var listOfPerson = ViewBag.Persons as IEnumerable<Persons>; // روش دوم // var listOfPerson = (IEnumerable<Persons>)ViewBag.Persons; var listOfPerson = ViewBag.Persons as IEnumerable<Persons>; } <table> <thead> <tr> <th> Id </th> <th> First Name </th> <th> Last Name </th> <th> Father Name </th> <th> Age </th> <th> Mobile </th> <th> Address </th> </tr> </thead> <tbody> @{foreach (var item in listOfPerson) { <tr> <td> @item.Id </td> <td> @item.FirstName </td> <td> @item.LastName </td> <td> @item.FatherName </td> <td> @item.Age </td> <td> @item.Mobile </td> <td> @item.Address </td> </tr> } } </tbody> </table>
پیاده سازی Open Search در ASP.NET MVC
پس از وارد کردن آدرس سایت، با فشردن دکمهی tab و یا حتی کلیک بر روی دکمهی tab ای که در تصویر مشخص شده، امکان جستجو را در سایت فراهم میکند:
public static bool TryGetNonEnumeratedCount(this IEnumerable<T> source, out int count);
if (movies.TryGetNonEnumeratedCount(out int count)) { Console.WriteLine($"The count is {count}"); } else { Console.WriteLine("Could not get a count of movies without enumerating the collection"); }
- الگوهای ابتدایی برای برنامه نویسی دات نت | www.dotnetdev.info
- امنیت Android مبتنی بر هسته لینوکس، آنچنان هم تعریفی ندارد | www.winbeta.net
- معرفی StimulReport نسخه Silverlight با ساپورت RightToLeft | www.nikamooz.com
- Wintellect's Power Collections for .NET | powercollections.codeplex.com
- DFA/NFA for .NET | github.com
- Doom 3 GPL source code | github.com
- Visual Studio Achievements | channel9.msdn.com
- امکان یکپارچگی Atmel AVR Studio 5 با ویژوال استودیو | channel9.msdn.com
- شروع به کار با MongoDB | net.tutsplus.com
- طرح Visual Studio Achievements و توجه به کیفیت کدهای ارائه شده | hadihariri.com
- کتابی رایگان در مورد Razor View Engine | www.kunal-chowdhury.com
- لیستی از کتابخانههای رایگان مفید مرتبط با دات نت فریم ورک | stackoverflow.com
- مقایسهای بین Silverlight و HTML5 | channel9.msdn.com
1) نصب پیشنیاز
الف) نصب VS 2012
و یا
ب) نصب بسته MVC4 مخصوص VS 2010 (این مورد جهت سرورهای وب نیز توصیه میشود)
پس از نصب باید به این نکته دقت داشت که پوشههای زیر حاوی اسمبلیهای جدید MVC4 هستند و نیازی نیست الزاما این موارد را از NuGet دریافت و نصب کرد:
C:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies C:\Program Files\Microsoft ASP.NET\ASP.NET MVC 4\Assemblies
2) نیاز است نوع پروژه ارتقاء یابد
به پوشه پروژه MVC3 خود مراجعه کرده و تمام فایلهای csproj و web.config موجود را با یک ادیتور متنی باز کنید (از خود ویژوال استودیو استفاده نکنید، زیرا نیاز است محتوای فایلهای پروژه نیز دستی ویرایش شوند).
در فایلهای csproj (یا همان فایل پروژه؛ که vbproj هم میتواند باشد) عبارت
{E53F8FEA-EAE0-44A6-8774-FFD645390401}
{E3E379DF-F4C6-4180-9B81-6769533ABE47}
3) به روز رسانی شماره نگارشهای قدیمی
سپس تعاریف اسمبلیهای قدیمی نگارش سه MVC و نگارش یک Razor را یافته (در تمام فایلها، چه فایلهای پروژه و چه تنظیمات):
System.Web.Mvc, Version=3.0.0.0 System.Web.WebPages, Version=1.0.0.0 System.Web.Helpers, Version=1.0.0.0 System.Web.WebPages.Razor, Version=1.0.0.0
System.Web.Mvc, Version=4.0.0.0 System.Web.WebPages, Version=2.0.0.0 System.Web.Helpers, Version=2.0.0.0 System.Web.WebPages.Razor, Version=2.0.0.0
4) به روز رسانی مسیرهای قدیمی
به علاوه اگر در پروژههای خود از اسمبلیهای قدیمی به صورت مستقیم استفاده شده:
C:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies C:\Program Files\Microsoft ASP.NET\ASP.NET MVC 3\Assemblies
C:\Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies C:\Program Files\Microsoft ASP.NET\ASP.NET MVC 4\Assemblies
5) به روز رسانی قسمت appSettings فایلهای کانفیگ
در کلیه فایلهای web.config برنامه، webpages:Version را یافته و شماره نگارش آنرا از یک به دو تغییر دهید:
<appSettings> <add key="webpages:Version" value="2.0.0.0" /> <add key="PreserveLoginUrl" value="true" /> </appSettings>
6) رسیدگی به وضعیت اسمبلیهای شرکتهای ثالث
ممکن است در این زمان از تعدادی کامپوننت و اسمبلی MVC3 تهیه شده توسط شرکتهای ثالث نیز استفاده نمائید. برای اینکه این اسمبلیها را وادار نمائید تا از نگارشهای MVC4 و Razor2 استفاده کنند، نیاز است bindingRedirectهای زیر را به فایلهای web.config برنامه اضافه کنید (در فایل کانفیگ ریشه پروژه):
<configuration> <!--... elements deleted for clarity ...--> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="4.0.0.0"/> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
7) استفاده از NuGet برای به روز رسانی بستههای نصب شده
یک سری از بستههای تشکیل دهنده MVC3 مانند موارد ذیل نیز به روز شدهاند که لازم است از طریق NuGet دریافت و جایگزین شوند:
Unobtrusive.Ajax.2
Unobtrusive.Validation.2
Web.Optimization.1.0.0
و ....
برای اینکار در solution explorer روی references کلیک راست کرده و گزینه Manage NuGet Packages را انتخاب کنید. در صفحه باز شده گزینه updates/all را انتخاب کرده و مواردی را که لیست میکند به روز نمائید (شامل جی کوئری، EF، structureMap و غیره خواهد بود).
8) اضافه کردن یک فضای نام جدید
بسته Web Optimization را از طریق NuGet دریافت کنید (برای یافتن آن bundling را جستجو کنید؛ نام کامل آن Microsoft ASP.NET Web Optimization Framework 1.0.0 است). این مورد به همراه پوشه MVC4 نیست و باید از طریق NuGet دریافت و نصب شود. (البته پروژههای جدید MVC4 شامل این مورد هستند)
در فایل وب کانفیگ، فضای نام System.Web.Optimization را نیز اضافه نمائید:
<pages> <namespaces> <add namespace="System.Web.Optimization" /> </namespaces> </pages>
پس از ارتقاء
اولین مشکلی که مشاهده شد:
بعد از rebuild به مقدار پارامتر salt که به نحو زیر در MVC3 تعریف شده بود، ایراد خواهد گرفت:
[ValidateAntiForgeryToken(Salt = "data123")]
علت هم این است که salt را اینبار به نحو صحیحی خودشان در پشت صحنه تولید و اعمال میکنند. بنابراین این یک مورد را کلا از کدهای خود حذف کنید که نیازی نیست.
مشکل بعدی:
در EF 5 جای یک سری از کلاسها تغییر کرده. مثلا ویژگیهای ForeignKey، ComplexType و ... به فضای نام System.ComponentModel.DataAnnotations.Schema منتقل شدهاند. در همین حد تغییر جهت کامپایل مجدد کدها کفایت میکند.
همچنین فایلهای پروژه موجود را باز کرده و EntityFramework, Version=4.1.0.0 را جستجو کنید. نگارش جدید 4.4.0.0 است که باید اصلاح شود (این موارد را بهتر است توسط یک ادیتور معمولی خارج از VS.NET ویرایش کنید).
در زمان نگارش این مطلب EF Mini Profiler با EF 5 سازگار نیست. بنابراین اگر از آن استفاده میکنید نیاز است غیرفعالش کنید.
اولین استفاده از امکانات جدید MVC4:
استفاده از امکانات System.Web.Optimization که ذکر گردید، میتواند اولین تغییر مفید محسوب شود.
برای اینکه با نحوه کار آن بهتر آشنا شوید، یک پروژه جدید MVC4 را در VS.NET (از نوع basic) آغاز کنید. به صورت خودکار یک پوشه جدید را به نام App_Start به ریشه پروژه اضافه میکند. داخل آن فایل مثال BundleConfig قرار دارد. این کلاس در فایل global.asax برنامه نیز ثبت شدهاست. باید دقت داشت در حالت دیباگ (compilation debug=true در وب کانفیگ) تغییر خاصی را ملاحظه نخواهید کرد.
تمام اینها خوب؛ اما من به نحو زیر از این امکان جدید استفاده میکنم:
using System.Collections.Generic; using System.IO; using System.Web; using System.Web.Optimization; namespace Common.WebToolkit { /// <summary> /// A custom bundle orderer (IBundleOrderer) that will ensure bundles are /// included in the order you register them. /// </summary> public class AsIsBundleOrderer : IBundleOrderer { public IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files) { return files; } } public static class BundleConfig { private static void addBundle(string virtualPath, bool isCss, params string[] files) { BundleTable.EnableOptimizations = true; var existing = BundleTable.Bundles.GetBundleFor(virtualPath); if (existing != null) return; var newBundle = isCss ? new Bundle(virtualPath, new CssMinify()) : new Bundle(virtualPath, new JsMinify()); newBundle.Orderer = new AsIsBundleOrderer(); foreach (var file in files) newBundle.Include(file); BundleTable.Bundles.Add(newBundle); } public static IHtmlString AddScripts(string virtualPath, params string[] files) { addBundle(virtualPath, false, files); return Scripts.Render(virtualPath); } public static IHtmlString AddStyles(string virtualPath, params string[] files) { addBundle(virtualPath, true, files); return Styles.Render(virtualPath); } public static IHtmlString AddScriptUrl(string virtualPath, params string[] files) { addBundle(virtualPath, false, files); return Scripts.Url(virtualPath); } public static IHtmlString AddStyleUrl(string virtualPath, params string[] files) { addBundle(virtualPath, true, files); return Styles.Url(virtualPath); } } }
چند نکته مهم در این کلاس وجود دارد:
الف) توسط AsIsBundleOrderer فایلها به همان ترتیبی که به سیستم اضافه میشوند، در حاصل نهایی ظاهر خواهند شد. حالت پیش فرض مرتب سازی، بر اساس حروف الفباء است و ... خصوصا برای اسکریپتهایی که ترتیب معرفی آنها مهم است، مساله ساز خواهد بود.
ب)BundleTable.EnableOptimizations سبب میشود تا حتی در حالت debug نیز فشرده سازی را مشاهده کنید.
ج) متدهای کمکی تعریف شده این امکان را میدهند تا بدون نیاز به کامپایل مجدد پروژه، به سادگی در کدهای Razor بتوانید اسکریپتها را اضافه کنید.
سپس نحوه جایگزینی تعاریف قبلی موجود در فایلهای Razor با سیستم جدید، به نحو زیر است:
@using Common.WebToolkit <link href="@BundleConfig.AddStyleUrl("~/Content/blueprint/print", "~/Content/blueprint/print.css")" rel="stylesheet" type="text/css" media="print"/> @BundleConfig.AddScripts("~/Scripts/js", "~/Scripts/jquery-1.8.0.min.js", "~/Scripts/jquery.unobtrusive-ajax.min.js", "~/Scripts/jquery.validate.min.js") @BundleConfig.AddStyles("~/Content/css", "~/Content/Site.css", "~/Content/buttons.css")
http://site/Content/blueprint/print?v=hash
@BundleConfig.AddStyles("~/Content/noty/css", "~/Content/noty/jquery.noty.css", "~/Content/noty/noty_theme_default.css")
پارامترهای بعدی، محل قرارگیری اسکریپتها و CSSهای برنامه هستند و همانطور که عنوان شد اینبار با خیال راحت میتوانید ترتیب معرفی خاصی را مدنظر داشته باشید؛ زیرا توسط AsIsBundleOrderer به صورت پیش فرض لحاظ خواهد شد.
به کمک آن میتوان عبارات پیچیده T-SQL را Parse و آنالیز کرد. البته باید در نظر داشت هرچند این بسته جهت SQL Server 2012 ارائه شده اما این اسمبلی با نگارشهای 2005 به بعد اس کیوال سرور کاملا سازگار است و اساسا نیازی هم به SQL Server ندارد. در ادامه مروری خواهیم داشت بر نحوه استفاده از آن.
یافتن کوئریهای * Select در بین انبوهی از اسکریپتها به کمک SQLDom
در مورد مضرات کوئریهای * select پیشتر مطلبی را در این سایت خواندهاید. در ادامه قصد داریم به کمک امکانات اسمبلی Microsoft.SqlServer.TransactSql.ScriptDom.dll، تعدادی عبارت T-SQL را آنالیز کرده و مشخص کنیم که آیا حاوی * select هستند یا خیر. کد کامل آنرا در ذیل مشاهده میکنید:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using Microsoft.SqlServer.TransactSql.ScriptDom; namespace DbCop { // Microsoft® SQL Server® 2012 Transact-SQL ScriptDom // SQL Server 2012 managed parser, Supports SQL Server 2005+ // SQLDom.msi (redist x86/x64) // http://www.microsoft.com/en-us/download/details.aspx?id=29065 // X86: http://go.microsoft.com/fwlink/?LinkID=239634&clcid=0x409 // X64: http://go.microsoft.com/fwlink/?LinkID=239635&clcid=0x409 // Program Files\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.TransactSql.ScriptDom.dll class Program { static void Main() { const string tSql = @" -- select * in PROCEDURE CREATE PROCEDURE dbo.SelectStarTest AS SELECT * FROM dbo.tbl1 go -- select * in PROCEDURE with TableVar Create PRocedure SelectAll AS Declare @X table(Id integer) Select * from @x go -- select * in PROCEDURE with ctex CREATE PROCEDURE dbo.SelectAllCte AS WITH ctex AS ( SELECT * FROM sys.objects ) SELECT * FROM ctex go -- normal select * select * from tbl1; select * from dbo.tbl2; "; IList<ParseError> errors; TSqlScript sqlFragment; using (var reader = new StringReader(tSql)) { var parser = new TSql110Parser(initialQuotedIdentifiers: true); sqlFragment = (TSqlScript)parser.Parse(reader, out errors); } if (errors != null && errors.Any()) { var sb = new StringBuilder(); foreach (var error in errors) sb.AppendLine(error.Message); throw new InvalidOperationException(sb.ToString()); } var i = 0; foreach (var batch in sqlFragment.Batches) { Console.WriteLine("Batch: {0}, Statement(s): {1}", ++i, batch.Statements.Count); foreach (var statement in batch.Statements) { processStatement(statement); } Console.WriteLine(); } Console.WriteLine("\nPress a key..."); Console.Read(); } private static void processStatement(TSqlStatement statement) { var createProcedureStatement = statement as CreateProcedureStatement; if (createProcedureStatement != null) { var statementList = createProcedureStatement.StatementList; foreach (var procedureStatement in statementList.Statements) { processStatement(procedureStatement); } } var selectStatement = statement as SelectStatement; if (selectStatement != null) { var query = selectStatement.QueryExpression; var selectElements = ((QuerySpecification)query).SelectElements; foreach (var selectElement in selectElements) { var expression = selectElement as SelectStarExpression; if (expression == null) continue; Console.WriteLine( "`Select *` detected @StartOffset:{0}, Line:{1}, T-SQL: {2}", expression.StartOffset, expression.StartLine, statementToString(selectStatement)); } } } private static string statementToString(TSqlFragment selectStatement) { var text = new StringBuilder(); for (var i = selectStatement.FirstTokenIndex; i <= selectStatement.LastTokenIndex; i++) { text.Append(selectStatement.ScriptTokenStream[i].Text); } return text.ToString(); } } }
توضیحات:
پس از نصب SQLDom.msi، ارجاعی را به اسمبلی زیر اضافه نمائید تا بتوانید کد فوق را کامپایل کنید:
Program Files\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.TransactSql.ScriptDom.dll
کار با ایجاد وهلهای از TSql110Parser شروع میشود. متد Parse آن، آرگومانی از نوع TextReader را قبول میکند. برای مثال با استفاده از StringReader میتوان محتوای یک متغیر رشتهای را به آن ارسال کرد و یا توسط StreamReader یک فایل sql را.
پس از فراخوانی متد Parse، بهتر است بررسی شود که آیا عبارت T-SQL دریافتی معتبر بوده است یا خیر. اینکار را توسط لیستی از ParseErrorهای دریافتی میتوان انجام داد.
خروجی متد Parse، حاوی یک سری Batch آنالیز شده است. هر عبارت Go در اینجا یک Batch را تشکیل میدهد. سپس در داخل هر batch به دنبال batch.Statements خواهیم گشت تا بتوان به عبارات T-SQL آنها دسترسی یافت.
در ادامه کار اصلی توسط متد processStatement صورت میگیرد. عبارات دریافتی، در حالت کلی از نوع TSqlStatement هستند اما در اصل میتوانند یکی از مشتقات آن نیز باشند. در اینجا فقط دو مورد CreateProcedureStatement و SelectStatement بررسی شدهاند (مطابق رشته tSql ابتدای مثال). هر دو عبارت، از کلاس TSqlStatement مشتق شدهاند.
در متد processStatement عبارات select معمولی و همچنین آنهایی که داخل رویههای ذخیره شده تعریف شدهاند، استخراج شده و در نهایت بررسی میشوند که آیا از نوع SelectStarExpression هستند یا خیر (همان * select صورت مساله).
خروجی مثال فوق به شرح زیر است:
Batch: 1, Statement(s): 1 `Select *` detected @StartOffset:140, Line:5, T-SQL: SELECT * FROM dbo.tbl1 Batch: 2, Statement(s): 1 `Select *` detected @StartOffset:368, Line:12, T-SQL: Select * from @x Batch: 3, Statement(s): 1 `Select *` detected @StartOffset:659, Line:22, T-SQL: WITH ctex AS ( SELECT * FROM sys.objects ) SELECT * FROM ctex Batch: 4, Statement(s): 2 `Select *` detected @StartOffset:753, Line:26, T-SQL: select * from tbl1; `Select *` detected @StartOffset:791, Line:27, T-SQL: select * from dbo.tbl2;
نسخه net core 2.2. Preview 3.، روز چهارشنبه 25 مهر، مطابق با 17 اکتبر منتشر شد. این نسخه شامل ویژگیهای جدیدی از جمله موارد زیر میباشد:
- تغییرات عمده در API
- Authorization Server
- بهبود کارآیی و سرعت
- پشتیبانی از Spatial Data برای SQL Server و SQLite
- پشتیبانی از Cosmos DB
- جایگزینی Bootstrap 4, Angular 6
مهمترین ویژگی مربوط به EF Core برای گروهی از برنامه نویسان، پشتیبانی از فیلدهای جغرافیایی یا همان Spatial Data میباشد.
نسخهی net core 2.2 RTM.، قبل از انتهای سال میلادی جاری منتشر خواهد شد و پس از آن آغاز به کار بر روی net core 3. خواهد بود. برای نسخهی net Core 3.، هدف بهبود برنامههای مبتنی بر Desktop و سازگاری آن با فرمت جدید csproj، اعلام شدهاست.
برای استفاده از ویژگیهای net core 2.2. باید نسخهی visual studio 2017 preview، یعنی ورژن Version 15.9.0 به بعد را نصب کنید. اگر صرفا dotnet core 2.2 را نصب کنید و از ویژوال استودیوی جاری قصد استفاده را داشته باشید، به شما پیغام میدهد که این نسخه قابلیت استفاده از دات نت 2.2 به بعد را ندارد.
برای تست و استفاده از net core 2.2 preview 3. مراحل زیر را طی کنید:
1- ابتدا آخرین انتشار ویژوال استودیو 2017، یعنی نسخهی پیشنمایش preview را از اینجا دریافت و نصب کنید. نسخه Enterprise را انتخاب کنید تا installer دانلود شود وشروع به نصب کند. حجم این نسخه، از نسخهی اصلی کمتر میباشد.
پس از نصب، این نسخه را میتوانید در کنار نسخهی اصلی، همزمان بر روی سیستم داشته باشید.
- برای نصب کلی بر روی سیستم، اینجا کلیک کنید و نسخهی SDK Installer مناسب دستگاه خود را دانلود کنید (64 یا 32 بیتی).
- برای استفادهی از EF Core آن در پروژه جاری میتوانید آنرا از اینجا دانلود و یا بوسیلهی دستور زیر نصب کنید:
Install-Package Microsoft.EntityFrameworkCore -Version 2.2.0-preview3-35497
3- پس از نصب، ویژوال استودیوی preview را از همان مسیر visual studio، اجرا کنید. یک پروژهی جدید از نوع وب را ایجاد کنید و فریمورک را بر روی بالاترین مقدار آن قرار دهید؛ مثل تصویر زیر:
بعد از ایجاد پروژه، میتوانید در solution Explorer، ارجاعات جدید را مشاهده کنید: