نظرات مطالب
شروع به کار با EF Core 1.0 - قسمت 10 - استفاده از امکانات بومی بانک‌های اطلاعاتی
رفع محدودیت «خروجی کوئری SQL، تنها باید معادل یکی از کلاس‌های موجودیت‌های شما باشد» در نگارش 2.1
در نگارش 2.1 مفهوم جدیدی به نام Query Types ارائه شده‌است که امکان نگاشت به خروجی‌های خاص بانک اطلاعاتی مانند Viewها و یا رویه‌های ذخیره شده را میسر می‌کند که این خروجی‌ها عموما مستقل از فیلدهای جداول و موجودیت‌های تعریف شده‌ی در برنامه هستند.
برای مثال فرض کنید یک View ویژه را بر اساس جدول و یا جداول بانک اطلاعاتی خود طراحی کرده‌اید:
using (var db = new BloggingContext())
{
   db.Database.ExecuteSqlCommand(
         @"CREATE VIEW View_BlogPostCounts AS 
             SELECT Name, Count(p.PostId) as PostCount from Blogs b
             JOIN Posts p on p.BlogId = b.BlogId
             GROUP BY b.Name");
}
خروجی این View که دو ستون name و PostCount را به همراه دارد، متناظر با موجودیت‌های اصلی برنامه نیست. برای تهیه نگاشتی به آن، ابتدا کلاس مدل متناظر با این ستون‌های بازگشتی را تهیه می‌کنیم:
public class BlogPostsCount
{
    public string BlogName { get; set; }
    public int PostCount { get; set; }
}

سپس برای معرفی آن به Context باید دو مرحله انجام شود:
الف) این کلاس به صورت DbQuery در Context معرفی می‌شود:
public class BloggingContext : DbContext
{
    public DbQuery<BlogPostsCount> BlogPostCounts { get; set; }
ب) در متد OnModelCreating همین Context، نگاشت این DbQuery به View یاد شده توسط متد ToView انجام می‌شود:
   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
      modelBuilder
           .Query<BlogPostsCount>().ToView("View_BlogPostCounts")
           .Property(v => v.BlogName).HasColumnName("Name");
    }
متد ToView الزاما نیازی به یک view ندارد. مفهوم آن صرفا یک خروجی فقط خواندنی است. برای مثال حتی در اینجا یک جدول بانک اطلاعاتی را هم می‌توانید ذکر کنید. اما مفهوم آن غیرقابل تغییر بودن خروجی کوئری‌های آن است. بنابراین باید دقت داشت که در اینجا مهم نیست که کلاس نگاشت تعریف شده دارای کلید هست یا خیر و ارجاعی از این کلاس را نمی‌توان در کلاس‌های موجودیت‌های اصلی مورد استفاده قرار داد.
از متد Property به این جهت استفاده شده‌است که در کلاس BlogPostsCount، خاصیت BlogName، متناظر با هیچکدام از ستون‌های بازگشتی View تعریف شده نیست. به همین جهت با استفاده از این متد مشخص کرده‌ایم که این خاصیت باید به کدام ستون بازگشتی، نگاشت شود.
و در آخر کوئری گرفتن از این DbQuery تعریف شده به صورت زیر است:
using (var db = new BloggingContext())
{
   var postCounts = db.BlogPostCounts.ToList();

مثال کامل این نکته
نظرات مطالب
EF Code First #1
جدول _MigrationHistiry را در اس کیو ال در فلدر System Tables قرار نداده است و آن را کنار دو جدول Posts و Blogs قرار داده است ؛ در صورتیکه در عکس شما این جدول به عنوان جدول سیستمی معرفی شده است. علت چیست؟
نظرات مطالب
ASP.NET MVC #20
با سلام؛ آیا امکان این است که ویرایش اطلاعات به صورت Inline درون خود جدول انجام شود ؟
نظرات مطالب
EF Code First #3
چطور من می‌تونم در code first یک جدول بدون کلید داشته باشم ؟
نظرات مطالب
معرفی و استفاده از DDL Triggers در SQL Server
باید از از حالت INSTEAD OF استفاده کنیم در DML Trigger ای که قراره نوشته بشه.
می‌توانیم در یک جدول از دیتابیس مان بر اساس یک شرط خاص, عملیات Insert,Delete,Update را مدیریت کنیم.
بعنوان مثال در قطعه کد زیر ما قبل از عملیات Insert در جدول tblTest چک میکنیم که اگر مقدار ستون FirstName برابر با null بود عملیات Insert آن رکورد در دیتابیس لغو شود.
ALTER TRIGGER [dbo].[Prevent_Befor_Insert_Null]
   ON  [dbTest].[dbo].[tblTest] 
   INSTEAD OF INSERT 
AS 
BEGIN
SET NOCOUNT ON
IF OBJECT_ID(N'dbTest.dbo.tblTest.FirstName') is null
BEGIN
DECLARE @Id int
SET @Id = (select Id from inserted)
RAISERROR ('مقدار فیلد نام نباید خالی باشد',16,1)
ROLLBACK
END
END

از دو طریق می‌توان به مقادیر فیلدهای رکورد جاری دسترس داشت:
1- استفاده از OBJECT_ID و ذکر نام فیلد مورد نظر
2- گرفتن فیلد مورد نظر از جدول INSERTED یا DELETED
DML Trigger‌ها دارای دو جدول خاص بنام‌های INSERTED و DELETED هستند که توسط خود SQL Server مدیریت می‌شوند.در حقیقت در پشت صحنه, ما با این دو جدول در هنگام تغییر مقادیر داده‌های جداول دیتابیس کار می‌کنیم و نمی‌توانیم بصورت مستقیم داده‌های جداول موجود در دیتا بیس مان را تغییر دهیم.
جدول INSERTED و DELETED حاوی رکورد جاری است که تحت تاثیر عمل درج, ویرایش و حذف در دیتابیس قرار گرفته است.
اطلاعات بیشتر در اینجا و اینجا
مطالب
فعال و غیر فعال کردن قیود
SQL Server قابلیت فعال(enable) و غیر فعال(disable) کردن دو قید کلید خارجی و check را برای ما مهیا کرده است.
ما می‌توانیم بعد از ساخت جدول و انتشار مقداری داده در آن قیدهایی را ایجاد کنیم. بطور پیشفرض اگر شرط قید ما بر قرار بود قید به طور صحیح ساخته می‌شود و اگر شرط قید ما بر قرار نباشد قید با خطای conflict مواجه خواهد شد.
بطور کلی غیر فعال کردن قیدها کار درستی نیست. ولی در برخی مواقع برای تسریع در اجرای کد می‌توانیم قید را غیر فعال کنیم. بطور مثال اگر یک میلیون داده قرار است در جدول درج شود و مطمئن هستیم که این داده‌ها جامعیت داده‌ها را حفظ می‌کنند آنگاه می‌توانیم قید را برای تسریع در عمل درج بطور موفق غیر فعال کنیم.

فعال و غیر فعال کردن از طریق DDL
با غیر فعال کردن قیود داده‌ها را در وضعیت نامناسبی قرار می‌دهیم ولی همان طور که اشاره شد بطور موفق اشکالی پیش نخواهد آمد.
در ادامه ابتدا طریقه غیرفعال کردن و مجددا فعال کردن قیود را توسط دستور alter table نشان خواهم داد سپس به سراغ امکانات ویزاردی می‌رویم. ابتدا یک جدول تک ستونه ایجاد می‌کنیم:
CREATE TABLE testTable
(column1 integer not  null);

الان هیچ قیدی روی جدول لحاظ نشده است. پس هر داده که در رنج domain ستون باشد را میتوانیم درج کنیم. پس بطور نمونه این داده‌ها را درج میکنیم:
INSERT INTO testTable
VALUES (-10), (0), (10), (20), (30), (40)

حالا تصمیم داریم قیدی روی ستون column1 بگذاریم که توسط آن تنها اعداد مثبت در جدول درج شوند. پس داریم:
ALTER TABLE testTable
WITH CHECK 
ADD CONSTRAINT NoNegative 
CHECK (column1 > 0);
ولی چون داده هایی در جدول از قبل وجود داشته اند که قید ما را نقض کنند این قید ساخته نخواهد شد و با پیغام زیر مواجه خواهیم شد:
The ALTER TABLE statement conflicted with the CHECK constraint "NoNegative".

برای ساخت این قید روی این داده‌ها تنها راه استفاده از کلید واژه‌های WITH NOCHECK است یعنی:
ALTER TABLE testTable
WITH NOCHECK 
ADD CONSTRAINT NoNegative 
CHECK (column1 > 0);

و اکنون سعی میکنیم یک مقدار منفی در جدول درج کنیم:
INSERT INTO testTable VALUES (-5)
  /*
 The INSERT statement conflicted with the CHECK constraint "NoNegative".
 */

اما قیدی که ساخته بودیم در جدول در حال اعمال شدن است. برای درج مقدار منفی باید غیر را غیر فعال کنیم.
ALTER TABLE TestTable
NOCHECK CONSTRAINT NoNegative

و حالا مقدار منفی را درج میکنیم. و برای برگرداندن وضعیت NOCHECK به وضعیت CHECK باید از کلید واژه‌های WITH NOCHECK استفاده کنیم. چرا که داده هایی در جدول درج شده اند که قید مورد نظر ما را نقض می‌کنند.
ALTER TABLE TestTable
WITH NOCHECK
CHECK CONSTRAINT NoNegative

فعال و غیر فعال کردن از طریق design
در قسمت object explorer قید مورد نظر را پیدا کرده و روی آن راست کلیک کرده و گزینه Modify را انتخاب کنید. سپس در پنجره باز شده در قسمت Table Designer تغییرات مورد نظر خود را اعمال کنید.