رفع محدودیت «خروجی کوئری SQL، تنها باید معادل یکی از کلاسهای موجودیتهای شما باشد» در نگارش 2.1
در نگارش 2.1 مفهوم جدیدی به نام Query Types ارائه شدهاست که امکان نگاشت به خروجیهای خاص بانک اطلاعاتی مانند Viewها و یا رویههای ذخیره شده را میسر میکند که این خروجیها عموما مستقل از فیلدهای جداول و موجودیتهای تعریف شدهی در برنامه هستند.
برای مثال فرض کنید یک View ویژه را بر اساس جدول و یا جداول بانک اطلاعاتی خود طراحی کردهاید:
خروجی این View که دو ستون name و PostCount را به همراه دارد، متناظر با موجودیتهای اصلی برنامه نیست. برای تهیه نگاشتی به آن، ابتدا کلاس مدل متناظر با این ستونهای بازگشتی را تهیه میکنیم:
سپس برای معرفی آن به Context باید دو مرحله انجام شود:
الف) این کلاس به صورت DbQuery در Context معرفی میشود:
ب) در متد OnModelCreating همین Context، نگاشت این DbQuery به View یاد شده توسط متد ToView انجام میشود:
متد ToView الزاما نیازی به یک 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"); }
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; }
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder .Query<BlogPostsCount>().ToView("View_BlogPostCounts") .Property(v => v.BlogName).HasColumnName("Name"); }
از متد Property به این جهت استفاده شدهاست که در کلاس BlogPostsCount، خاصیت BlogName، متناظر با هیچکدام از ستونهای بازگشتی View تعریف شده نیست. به همین جهت با استفاده از این متد مشخص کردهایم که این خاصیت باید به کدام ستون بازگشتی، نگاشت شود.
و در آخر کوئری گرفتن از این DbQuery تعریف شده به صورت زیر است:
مثال کامل این نکته
using (var db = new BloggingContext()) { var postCounts = db.BlogPostCounts.ToList();
مثال کامل این نکته