The April release of the Azure Data Studio. Included in this release is:
- Added a new Welcome page.
- Added new markdown toolbar for Notebooks.
- Announcing KQL Magic support in Notebooks.
- Charting in SQL Notebooks can now be saved.
- Announcing improvements to Azure Data Studio dashboards.
- Support for Always Encrypted.
- Bug fixes.
یکی از مهمترین قسمتهای مدل سازی موجودیتها، تعیین نوعهای صحیح ستونها و همچنین تعیین اندازهی مناسبی برای آنها است؛ به همراه تعیین اجباری بودن یا نبودن مقدار دهی آنها.
تعیین اجباری بودن یا نبودن ستونها در EF Core
به صورت پیش فرض در EF Core، هر نوع CLR ایی که نال پذیر باشد، به صورت یک ستون اختیاری در نظر گرفته میشود؛ مانند:
و هر ستونی که نوع CLR آن نال پذیر نباشد، مقدار دهی آن در EF Core اجباری است؛ مانند:
همچنین باید دقت داشت که حتی اگر در تنظیمات نگاشتهای برنامه به صورت اختیاری تعریف شوند، باز هم EF Core آنها را اجباری درنظر میگیرد.
برای لغو اختیاری بودن یک خاصیت نال پذیر میتوان از ویژگی Required استفاده کرد:
نوع string نال پذیر است. برای لغو این وضعیت میتوان از ویژگی Required استفاده کرد که در سمت بانک اطلاعاتی نیز به not null ترجمه میشود.
و یا معادل Fluent API آن با استفاده از ذکر متد IsRequired است:
با توجه به این توضیحات، نیازی نیست در بالای یک خاصیت از نوع int، ویژگی Required را ذکر کرد. چون int نال پذیر نیست، مقدار دهی آن اجباری است.
کار با رشتهها در EF Core
ذکر یک خاصیت رشتهای به این صورت:
به معنای نال پذیر بودن این ستون است (چون Required تعریف نشدهاست) و همچنین نوع و طول آن در SQL Server به nvarchar max تنظیم میشود. این تنظیم طول هرچند در مورد SQL Server صادق است، اما ممکن است در SQL Server CE به nvarchar 4000 تفسیر شود (و این مشکل را به همراه داشته باشد که چرا نمیتوان متون طولانی را در آن ثبت کرد). به عبارتی عدم ذکر دقیق طول یک خاصیت رشتهای، در پروایدرهای مختلف، ممکن است معانی مختلفی را به همراه داشته باشد. بنابراین نیاز است طول خواص رشتهای حتما ذکر شوند تا در تمام بانکهای اطلاعاتی با دقت کامل و بدون حدس و گمان تنظیم گردند.
برای تعیین طول دقیق یک فیلد رشتهای، میتوان از ویژگیهای StringLength و یا MaxLength با ذکر اندازهای استفاده کرد.
برای تعیین صریح یک فیلد رشتهای به حداکثر مقدار آن بهتر است ویژگی MaxLength را بدون ذکر پارامتری قید کرد. این مورد جهت سازگاری با بانکهای اطلاعاتی مختلف ضروری است.
معادل این تنظیمات با روش Fluent API به صورت زیر است:
برای تعیین صریح طول یک فیلد رشتهای:
و برای تعیین صریح nvarchar max بودن آن فیلد:
حالت پیش فرض EF Core، کار با رشتههای یونیکد است. یعنی تمام فیلدهای فوق به nvarchar تفسیر میشوند و این n ایی که در ابتدا ذکر شدهاست به معنای یونیکد بودن آن است. اگر میخواهید این پیشفرض تعیین نوع یونیکد را تغییر دهید، میتوان از ویژگی Column استفاده کرد:
البته اگر اطلاعاتی را که با آن کار میکنید چندزبانی و یونیکد هستند، بهتر است این مورد را تغییر ندهید.
نکتهای در مورد تغییر نوع خواص: اگر از متد HasColumnType و یا ویژگی Column به نحو فوق استفاده کردید، نیاز است طول رشته را صریحا مشخص کنید. در غیر اینصورت در حین migration خطای ذیل را دریافت خواهید کرد:
در اینجا عنوان میکند که اگر مقصود شما varchar max است، ویژگی MaxLength را حذف کرده و تنها بنویسید:
نکتهای در مورد ایندکسها: در قسمت قبل عنوان شد که میتوان بر روی خواص، ایندکس منحصربفرد اعمال کرد. در مورد رشتهها در SQL Server، اگر طول فیلد مدنظر حداکثر تا 900 بایت باشد، یک چنین کاری را میتوان انجام داد. البته این محدودیت 900 بایتی تا SQL Server 2014 وجود دارد. این سقف در SQL Server 2016 به 1700 بایت افزایش یافتهاست (900bytes for a clustered index. 1,700 for a nonclustered index). بنابراین چون نوع پیش فرض ستونهای رشتهای، یونیکد و nvarchar درنظر گرفته میشود، حداکثر طول امنی را که میتوان برای آن تعریف کرد، مساوی 450 است (نصف 900 بایت). به همین جهت ذکر ایندکس منحصربفرد بر روی یک ستون رشتهای، باید به همراه ذکر اجباری حداکثر طول مساوی 450 آن باشد.
کار با اعداد در EF Core
کلاس نمونهای را با ساختار ذیل درنظر بگیرید:
پس از اعمال مهاجرتها و به روز رسانی ساختار بانک اطلاعاتی، به ساختار ذیل خواهیم رسید:
همانطور که ملاحظه میکنید، نوع bool دات نت به نوع bit در SQL Server، نوع long به bigint، نوع short به smallint، نوع int به int و نوع byte به tinyint نگاشت شدهاند.
نکتهای در مورد اعداد اعشاری: توصیه شدهاست در تعاریف موجودیتهای خود بهتر است از نوعهای float و یا double استفاده نکنید. برای کار با اعداد اعشاری از نوع decimal استفاده نمائید تا بتوانید از قابلیت مقایسهی دقیق آنها استفاده کنید. اطلاعات بیشتر: «روش صحیح مقایسه دو عدد اعشاری با هم»
کار با تاریخ در EF Core
اگر به تصویر فوق دقت کنید، نوع DateTime دات نت به datetime2 در سمت SQL Server ترجمه شدهاست:
اگر در دادههای خود نیازی به زمان ندارید، میتوان این نوع پیش فرض را با ویژگی Column که پیشتر بحث شد، به date تغییر داد.
اطلاعات بیشتر: «کنترل نوعهای داده با استفاده از EF در SQL Server»
به علاوه در دات نت نوع DateTime از نوع value type است. بنابراین همانطور که در ابتدای بحث نیز عنوان شد، مقدار دهی آن اجباری است؛ مگر آنکه آنرا نال پذیر تعریف کنید.
کار با مباحث همزمانی در EF Core
EF Core به صورت پیش فرض، فرض میکند رکوردی را که با آن در حال کار هستید، توسط هیچ کاربر دیگری در شبکه تغییر نیافتهاست و تغییرات شما را در حین فراخوانی متد SaveChanges ذخیره میکند. اگر علاقمند هستید که EF Core در صورت تغییر مقدار خاصیت خاصی توسط سایر کاربران، این مساله را با صدور استثنایی به شما اطلاع رسانی کند، از ویژگی ConcurrencyCheck
و یا متد IsConcurrencyToken حالت Fluent API استفاده نمائید:
در این حالت کوئری به روز رسانی، علاوه بر فیلد Id رکورد، حاوی فیلد Name نیز خواهد بود (در حین تشکیل شرط یافتن رکورد) و اگر در بین فاصلهی یافتن شخص و به روز رسانی نام او، شخص دیگری اینکار را انجام داده باشد، این به روز رسانی موفقیت آمیز نبوده و استثنایی صادر میشود.
اگر علاقمند هستید که تمام فیلدهای جدول تحت نظر قرارگیرند، میتوان از روش ویژهای به نام Timestamp/row version استفاده کرد:
با معادل Fluent API ذیل:
در مورد ValueGeneratedOnAddOrUpdate در قسمت قبل بحث کردیم. فیلد TimeStamp نیز جزو فیلدهای ویژهای است که SQL Server به صورت خودکار قادر است آنرا مقدار دهی کند و زمانیکه ValueGeneratedOnAddOrUpdate قید میشود، یعنی این فیلد همواره با فراخوانی متد SaveChanges، به صورت خودکار مقدار دهی خواهد شد (و نیازی نیست تا توسط برنامه مقدار دهی شود).
در این حالت در حین به روز رسانی یک چنین رکوردی، اگر از زمان کوئری آن (یافتن رکورد) و ذخیره سازی آن، شخص دیگری آنرا تغییر داده باشد، به علت عدم تطابق Timestamp ها، عملیات به روز رسانی باشکست روبرو شده و یک استثناء صادر میشود.
تعیین اجباری بودن یا نبودن ستونها در EF Core
به صورت پیش فرض در EF Core، هر نوع CLR ایی که نال پذیر باشد، به صورت یک ستون اختیاری در نظر گرفته میشود؛ مانند:
string, int?, byte[]
int, decimal, bool, DateTime
برای لغو اختیاری بودن یک خاصیت نال پذیر میتوان از ویژگی Required استفاده کرد:
[Required] public string Url { get; set; }
و یا معادل Fluent API آن با استفاده از ذکر متد IsRequired است:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>() .Property(b => b.Url) .IsRequired(); }
کار با رشتهها در EF Core
ذکر یک خاصیت رشتهای به این صورت:
public string FirstName { get; set; }
[StringLength(450)] public string FirstName { get; set; } [MaxLength(450)] public string LastName { get; set; } [MaxLength] public string Address { get; set; }
برای تعیین صریح یک فیلد رشتهای به حداکثر مقدار آن بهتر است ویژگی MaxLength را بدون ذکر پارامتری قید کرد. این مورد جهت سازگاری با بانکهای اطلاعاتی مختلف ضروری است.
معادل این تنظیمات با روش Fluent API به صورت زیر است:
برای تعیین صریح طول یک فیلد رشتهای:
modelBuilder.Entity<Person>() .Property(x => x.Address) .HasMaxLength(450);
modelBuilder.Entity<Person>() .Property(x => x.Address) .HasColumnType("nvarchar(max)");
[Column(TypeName = "varchar")] [MaxLength] public string Address { get; set; }
نکتهای در مورد تغییر نوع خواص: اگر از متد HasColumnType و یا ویژگی Column به نحو فوق استفاده کردید، نیاز است طول رشته را صریحا مشخص کنید. در غیر اینصورت در حین migration خطای ذیل را دریافت خواهید کرد:
Data type 'varchar' is not supported in this form. Either specify the length explicitly in the type name, for example as 'varchar(16)', or remove the data type and use APIs such as HasMaxLength to allow EF choose the data type.
[Column(TypeName = "varchar(max)")]
نکتهای در مورد ایندکسها: در قسمت قبل عنوان شد که میتوان بر روی خواص، ایندکس منحصربفرد اعمال کرد. در مورد رشتهها در SQL Server، اگر طول فیلد مدنظر حداکثر تا 900 بایت باشد، یک چنین کاری را میتوان انجام داد. البته این محدودیت 900 بایتی تا SQL Server 2014 وجود دارد. این سقف در SQL Server 2016 به 1700 بایت افزایش یافتهاست (900bytes for a clustered index. 1,700 for a nonclustered index). بنابراین چون نوع پیش فرض ستونهای رشتهای، یونیکد و nvarchar درنظر گرفته میشود، حداکثر طول امنی را که میتوان برای آن تعریف کرد، مساوی 450 است (نصف 900 بایت). به همین جهت ذکر ایندکس منحصربفرد بر روی یک ستون رشتهای، باید به همراه ذکر اجباری حداکثر طول مساوی 450 آن باشد.
کار با اعداد در EF Core
کلاس نمونهای را با ساختار ذیل درنظر بگیرید:
public class Person { public int Id { set; get; } public DateTime? DateAdded { set; get; } public DateTime? DateUpdated { set; get; } [StringLength(450)] public string FirstName { get; set; } [MaxLength(450)] public string LastName { get; set; } //[Column(TypeName = "varchar")] [MaxLength] public string Address { get; set; } //bit public bool IsActive { get; set; } //tiny Int public byte Age { get; set; } //small Int public short Short { get; set; } //int public int Int32 { get; set; } //Big int public long Long { get; set; } }
همانطور که ملاحظه میکنید، نوع bool دات نت به نوع bit در SQL Server، نوع long به bigint، نوع short به smallint، نوع int به int و نوع byte به tinyint نگاشت شدهاند.
نکتهای در مورد اعداد اعشاری: توصیه شدهاست در تعاریف موجودیتهای خود بهتر است از نوعهای float و یا double استفاده نکنید. برای کار با اعداد اعشاری از نوع decimal استفاده نمائید تا بتوانید از قابلیت مقایسهی دقیق آنها استفاده کنید. اطلاعات بیشتر: «روش صحیح مقایسه دو عدد اعشاری با هم»
کار با تاریخ در EF Core
اگر به تصویر فوق دقت کنید، نوع DateTime دات نت به datetime2 در سمت SQL Server ترجمه شدهاست:
CREATE TABLE [dbo].[Persons]( [DateAdded] [datetime2](7) NULL, [DateUpdated] [datetime2](7) NULL,
اطلاعات بیشتر: «کنترل نوعهای داده با استفاده از EF در SQL Server»
به علاوه در دات نت نوع DateTime از نوع value type است. بنابراین همانطور که در ابتدای بحث نیز عنوان شد، مقدار دهی آن اجباری است؛ مگر آنکه آنرا نال پذیر تعریف کنید.
کار با مباحث همزمانی در EF Core
EF Core به صورت پیش فرض، فرض میکند رکوردی را که با آن در حال کار هستید، توسط هیچ کاربر دیگری در شبکه تغییر نیافتهاست و تغییرات شما را در حین فراخوانی متد SaveChanges ذخیره میکند. اگر علاقمند هستید که EF Core در صورت تغییر مقدار خاصیت خاصی توسط سایر کاربران، این مساله را با صدور استثنایی به شما اطلاع رسانی کند، از ویژگی ConcurrencyCheck
[ConcurrencyCheck] public string Name { set; get; }
modelBuilder.Entity<Person>() .Property(p => p.Name) .IsConcurrencyToken();
اگر علاقمند هستید که تمام فیلدهای جدول تحت نظر قرارگیرند، میتوان از روش ویژهای به نام Timestamp/row version استفاده کرد:
[Timestamp] public byte[] Timestamp { get; set; }
modelBuilder.Entity<Blog>() .Property(p => p.Timestamp) .ValueGeneratedOnAddOrUpdate() .IsConcurrencyToken();
در این حالت در حین به روز رسانی یک چنین رکوردی، اگر از زمان کوئری آن (یافتن رکورد) و ذخیره سازی آن، شخص دیگری آنرا تغییر داده باشد، به علت عدم تطابق Timestamp ها، عملیات به روز رسانی باشکست روبرو شده و یک استثناء صادر میشود.
مسیرراهها
Entity framework code-first
شروع به کار با EF Code first
برای تکمیل بحث نیاز است تغییرات انجام شده از نگارش 4 به 6 را نیز مد نظر داشته باشید:
آشنایی با مباحث Migrations
آشنایی با تنظیمات نگاشتها به دو روش استفاده از ویژگیها و Fluent API
اعتبارسنجی و بررسی استثناءها
ردیابی تغییرات
استفاده از SQL خام و بانکهای اطلاعاتی متفاوت
نکات مهم کوئری نویسی در EF
استفاده از EF در WPF
لایه بندی پروژههای EF Code first
پروژههای انجام شده با EF Code first
برای تکمیل بحث نیاز است تغییرات انجام شده از نگارش 4 به 6 را نیز مد نظر داشته باشید:
- ارتقاء به Entity framework 6 و استفاده از بانکهای اطلاعاتی غیر از SQL Server
- بروز رسانی استفاده از SqlServer Compact در Entityframework 6.0
آشنایی با مباحث Migrations
- آشنایی با Code first migrations : قسمت اول و دوم
- وادار کردن EF Code first به ساخت بانک اطلاعاتی پیش از شروع به کار برنامه
- بررسی خطاهای متداول عملیات Migration در حین به روز رسانی پروژههای EF Code First
- بازسازی جدول MigrationHistory با کد نویسی در EF Code first
- استفاده از چندین Context در EF 6 Code first
آشنایی با تنظیمات نگاشتها به دو روش استفاده از ویژگیها و Fluent API
- امکانات مهیا جهت تنظیم ویژگیهای مدلهای برنامه در EF Code first
- تعیین شمای جداول بانکی در EF Code First
- بررسی تعاریف نگاشتها به کمک متادیتا در EF Code first
- بررسی Fluent API جهت تعریف نگاشت کلاسها به بانک اطلاعاتی
- مدیریت روابط بین جداول در EF Code first به کمک Fluent API
- ادامه بحث بررسی جزئیات نحوه نگاشت کلاسها به جداول، توسط EF Code firs
- SQL Server CE و ثبت متون طولانی در EF Code first
- بازنویسی سادهتر پیش فرضهای EF Code first در نگارش 6 آن
- مباحث تکمیلی مدلهای خود ارجاع دهنده در EF Code first
- بررسی تفصیلی رابطه Many-to-Many در EF Code first
- تقسیم جدول در Entity Framework Code First
- کار با کلیدهای اصلی و خارجی در EF Code first
- تنظیمات ارث بری کلاسها در EF Code first
- ایندکس منحصر به فرد با استفاده از Data Annotation در EF Code First
- ایجاد ایندکس منحصربفرد در EF Code first به صورت Fluent API
- افزودن خودکار کلاسهای تنظیمات نگاشتها در EF Code first
- خودکار کردن تعاریف DbSetها در EF Code first
- بررسی خطای cycles or multiple cascade paths و یا cyclical reference در EF Code first
- بالا بردن سرعت بارگذاری اولیه EF Code first با تعداد مدلهای زیاد
اعتبارسنجی و بررسی استثناءها
- Entity Framework و InnerException
- استثناهایی که باید حین استفاده از EF Code first بررسی شوند
- اعتبارسنجی در Entity framework Code first
ردیابی تغییرات
- ردیابی تغییرات در EF Code first
- ردیابی تغییرات در Entity Framework، بخش اول
- چند نکته کاربردی درباره Entity Framework
- نمایش خروجی SQL کدهای Entity framework 6 در کنسول دیباگ ویژوال استودیو
- بالا بردن سرعت DbContext هنگام ثبت دادههای زیاد
- استفاده از EF در اپلیکیشنهای N-Tier : قسمت اول
- نحوه کاهش مصرف حافظه EF Code first حین گزارشگیری از اطلاعات
استفاده از SQL خام و بانکهای اطلاعاتی متفاوت
نکات مهم کوئری نویسی در EF
- نوشتن پرس و جو در Entity Framework با استفاده از LINQ To Entity ، قسمت اول، دوم و سوم
- تفاوت بین IQueryable و IEnumerable در حین کار با ORMs
- Lazy loading و eager loading
- روشهایی برای بهبود سرعت برنامههای مبتنی بر Entity framework
- نکاتی در مورد استفاده از توابع تجمعی در Entity framework
- کوئریهایی با قابلیت استفادهی مجدد
- شبیه سازی outer Join در entity framework
- اعمال توابع تجمعی بر روی چند ستون در Entity framework
- متد LastOrDefault در EF
- Func یا Expression Func در EF
- درج یک باره چندین رکورد بصورت همزمان هنگام استفاده از ORMها
- استفاده از خواص راهبری در Entity framework بجای Join نویسی
- مرتب سازی رکوردها به صورت اتفاقی در Entity framework
- استفاده از خواص راهبری در EF Code first جهت ساده سازی کوئریها
- یافتن مقادیر نال در Entity framework
- واکشی اطلاعات به صورت chunk chunk (تکه تکه) و نمایش در ListView
- امنیت در LINQ to SQL
- کارهایی جهت بالابردن کارآیی - قسمت اول
- کارهایی جهت بالابردن کارآیی - قسمت دوم
- کارهایی جهت بالابردن کارآیی - قسمت سوم
استفاده از EF در WPF
لایه بندی پروژههای EF Code first
- پیشنیاز: مطالعه کامل دوره تزریق وابستگیها
- استفاده از الگوی Repository اضافی در EF Code first؛ آری یا خیر؟!
- Repositoryها روی UnitOfWork ایده خوبی نیستند
- پیاده سازی الگوی Context Per Request در برنامههای مبتنی بر EF Code first
- پیاده سازی UnitOfWork به وسیله MEF
پروژههای انجام شده با EF Code first
مقالهای هست اینجا در مورد کارآیی CLR در SQL Server. به نظر میرسه سریعتر است حدود 11 درصد نسبت به T-SQL معمولی. برای پارتشین بندی میتونید اینکار رو انجام بدید فقط این نوع خاص قابل انتخاب نیست. مابقی فیلدها رو میتونید انتخاب کنید.
نظرات اشتراکها
اسکیوال سرور ۲۰۱۹ نسخه نهایی ریلیز شد
15.0.2070.41 | 2019.150.2070.41 | 4517790 Servicing Update (GDR1) for SQL Server 2019 RTM | 2019-11-04 *new |
15.0.2000.5 | 2019.150.2000.5 | Microsoft SQL Server 2019 RTM RTM | 2019-11-04 |