ایجاد Non-Entity Types یا Projections از روی جداول دیتابیس بصورت SqlRaw
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 باشه