ایجاد Non-Entity Types یا Projections از روی جداول دیتابیس بصورت SqlRaw

آخرین بروز رسانی: 1400/12/25

EF Core مکانیزم هایی  فراهم کرده است برای اجرای  SQL  خام ,مستقیماً روی دیتابیس برای شرایطی که نمی توانید(یا نمیخواهید) از LINQ برای کوئری گرفتن استفاده کنید (مثلاً جستجوی متن کامل). شرایطی چون :
SQL تولید شده به اندازه کافی کارآمد نیست، 
می خواهید از store produreهای موجود استفاده کنید. 

 

کد زیر نمونه ای از این مورد هست

public class Book
{
    public int BookId { get; set; }
    public string Title { get; set; }
    public Author Author { get; set; }
    public int AuthorId{ get; set; }
    public string Isbn { get; set; }
}
...
public class SampleContext : DbContext
{
    public DbSet<Book> Books { get; set; }
}
...
using (var context = new SampleContext())
{
    var books = context.Books.FromSqlRaw("SELECT BookId, Title, AuthorId, Isbn FROM Books").ToList();
}

 

ولی مشکل اینحاست که برای این کار شما باید  DbSetیی که میخواهید کوئری روی آن اجرا کنید رو انتخاب کنید ولی ما میخایم خروجی یه کلاسی باشه که جز entityها  و DbSetهای دیتابیس و DbContextمون نیست (Non-Entity Types  یا Projections )

فکر کنید جدول دیتابیسی دارید با این شرایط

)CREATE TABLE Cities 
  Id BIGINT IDENTITY
 ,Name NVARCHAR(128) NULL
 ,ParentId BIGINT NULL
 ,Code INT NULL
 ,CONSTRAINT PK_Cities PRIMARY KEY CLUSTERED (Id)
( ON [PRIMARY]
GO

ALTER TABLE Cities
ADD CONSTRAINT FK_Cities_Cities_ParentId FOREIGN KEY (ParentId) REFERENCES dbo.Cities (Id)
GO

کلاس entity معادلش میشه

   public class City
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public int? Code { get; set; }
        public long? ParentId { get; set; }
        public List<City> Childs { get; set; } = new List<City>();
    }

حالا میخام یه view ازش داشته باشم

    public class NonEntityCity
    {
        public long Id { get; set; }
        public string Name { get; set; }
        public int? Code { get; set; }
        public string Parent { get; set; }
    }
var citieyViews = await _db.Set<NonEntityCity>()
                          .FromSqlRaw("SELECT c1.id,c1.name,c1.code,parent=c2.Name FROM Cities c1 LEFT JOIN Cities c2 ON c2.id=c1.ParentId")
                          .ToListAsync();                           

 

فقط 2 نکته:

- فیلدهای داخل  select  باید معادلش تو کلاس View  پراپرتی وجود داشته باشه
- فیلد Id  حتما باید تو کلاس View  باشه

 

نظر دهید

آدرس ایمیل شما منتشر نخواهد شد. فیلدهای الزامی علامت گذاری شده اند *