Stored Procedure در Entity Framework-Code First
سه شنبه 1 دی 1394روش Code First تمام موجودیت ها((Entity را برای انجام عملیات CRUD و از طریق دسترسی مستقیم به جداول پایگاه داده، پیکربندی می کند. با استفاده از Entity Framework 6.0 می توانیم مدل Code First خود را توسط یک Stored Procedure برای تمام Entity های مدل پیکربندی کنیم.
Map کردن Stored Procedure ها
برای استفاده از Stored Procedure با مدل Code First، باید متد OnModelCreating از کلاس DBContext را override( باز نویسی) کرده و کد زیر را برای map کردن Stored Procedure اضافه کنیم.
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<yourEntity>().MapToStoredProcedures(); }
متد MapToStoreProcedures دو متد به صورت overloaded دارد، یکی از آن متدها بدون پارامتر است. این متد از قراردادهای Entity Framework code-first برای راه اندازی Stored Procedure ها استفاده می کند. متد دیگر یک Action method است و به ما اجازه می دهد تا نام، پارامتر، شمای Stored Procedure را سفارشی(Customize) کنیم.
به طور پیش فرض insert Stored Procedure یک پارامتر برای هر Property به جز Property های مشخص شده به صورت تولید شده و ذخیره شده، دارد(مانند identity و computed). این Stored Procedure مقدار ستون store generated را برمی گرداند. یک Stored Procedure به روز شده، یک پارامتر برای هر Property مشخص به صورت store generated دارد(فقط computed). این Stored Procedure نتیجه مجموعه ای از Property های محاسبه شده را برمی گرداند. Delete Stored Procedure یک پارامتر دارد که بخشی از کلید entity می باشد. این Stored Procedure چیزی برنمی گرداند.
مثال
کلاس زیر را در نظر بگیرید:
public class DepartmentMaster { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int DepartmentId { get; set; } public string Code { get; set; } public string Name { get; set; } public List<EmployeeMaster> Employees { get; set; } } public class EmployeeMaster { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int EmployeeId { get; set; } public string Code { get; set; } public string Name { get; set; } public int DepartmentId { get; set; } public DepartmentMaster Department { get; set; } }
کلاس context ما به صورت زیر است. در این کلاس، متد OnModelCreating را برای map کردن این Stored Procedure با موجودیتEmployeeMaster بازنویسی(Override) می کنیم.
public class EntitiesContext : DbContext { public EntitiesContext() : base("name=Entities") { } public DbSet<DepartmentMaster> Departments { get; set; } public DbSet<EmployeeMaster> Employees { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<EmployeeMaster>() .MapToStoredProcedures(s => s.Insert(u => u.HasName("InsertEmployee", "dbo")) .Update(u => u.HasName("UpdateEmployee", "dbo")) .Delete(u => u.HasName("DeleteEmployee", "dbo")) ); } }
حالا به ترتیب مراحل زیر را برای migration انجام می دهیم.
مرحله 1:
با دستور زیر در کنسول migration را فعال می کنیم:
enable-migrations -ContextTypeName CodeFirstStoredProcedure.EntitiesContext -MigrationsDirectory:EntitiesMigrations
مرحله 2:
تنظیمات Migration را اضافه می کنیم:
Add-Migration -configuration CodeFirstStoredProcedure.EntitiesMigrations.Configuration InitialEntities
اضافه کردن دستور Migration یک کلاس Dbmigration ایجاد می کند. این کلاس DB Migration تعریفی برای تمام Stored Procedure ها دارد.
public partial class InitialEntities : DbMigration { public override void Up() { CreateStoredProcedure( "dbo.InsertEmployee", p => new { Code = p.String(), Name = p.String(), DepartmentId = p.Int(), }, body: @"INSERT [dbo].[EmployeeMasters]([Code], [Name], [DepartmentId]) VALUES (@Code, @Name, @DepartmentId) DECLARE @EmployeeId int SELECT @EmployeeId = [EmployeeId] FROM [dbo].[EmployeeMasters] WHERE @@ROWCOUNT > 0 AND [EmployeeId] = scope_identity() SELECT t0.[EmployeeId] FROM [dbo].[EmployeeMasters] AS t0 WHERE @@ROWCOUNT > 0 AND t0.[EmployeeId] = @EmployeeId" ); CreateStoredProcedure( "dbo.UpdateEmployee", p => new { EmployeeId = p.Int(), Code = p.String(), Name = p.String(), DepartmentId = p.Int(), }, body: @"UPDATE [dbo].[EmployeeMasters] SET [Code] = @Code, [Name] = @Name, [DepartmentId] = @DepartmentId WHERE ([EmployeeId] = @EmployeeId)" ); CreateStoredProcedure( "dbo.DeleteEmployee", p => new { EmployeeId = p.Int(), }, body: @"DELETE [dbo].[EmployeeMasters] WHERE ([EmployeeId] = @EmployeeId)" ); } public override void Down() { DropStoredProcedure("dbo.DeleteEmployee"); DropStoredProcedure("dbo.UpdateEmployee"); DropStoredProcedure("dbo.InsertEmployee"); } }
مرحله 3:
پایگاه داده را با استفاده از دستور زیر Update می کنیم:
- configuration:CodeFirstStoredProcedure.EntitiesMigrations.Configuration –Verbose
دستور Update data base جداول و Stored Procedure را ایجاد کرده و تعریف Stored Procedure به صورت زیر می شود:
CREATE PROCEDURE [dbo].[InsertEmployee] @Code [nvarchar](max), @Name [nvarchar](max), @DepartmentId [int] AS BEGIN INSERT [dbo].[EmployeeMasters]([Code], [Name], [DepartmentId]) VALUES (@Code, @Name, @DepartmentId) DECLARE @EmployeeId int SELECT @EmployeeId = [EmployeeId] FROM [dbo].[EmployeeMasters] WHERE @@ROWCOUNT > 0 AND [EmployeeId] = scope_identity() SELECT t0.[EmployeeId] FROM [dbo].[EmployeeMasters] AS t0 WHERE @@ROWCOUNT > 0 AND t0.[EmployeeId] = @EmployeeId END GO CREATE PROCEDURE [dbo].[UpdateEmployee] @EmployeeId [int], @Code [nvarchar](max), @Name [nvarchar](max), @DepartmentId [int] AS BEGIN UPDATE [dbo].[EmployeeMasters] SET [Code] = @Code, [Name] = @Name, [DepartmentId] = @DepartmentId WHERE ([EmployeeId] = @EmployeeId) END GO CREATE PROCEDURE [dbo].[DeleteEmployee] @EmployeeId [int] AS BEGIN DELETE [dbo].[EmployeeMasters] WHERE ([EmployeeId] = @EmployeeId)
کد تست
در Test Code یک رکورد به جدول EmployeeMaster وارد می کنیم:
static void Main(string[] args) { using (EntitiesContext context = new EntitiesContext()) { EmployeeMaster employee = new EmployeeMaster(); employee.Code = "A0001"; employee.Name = "Jignesh Trivedi"; employee.DepartmentId = 1; context.Employees.Add(employee); context.SaveChanges(); Console.ReadLine(); } }
کد زیر می تواند برای ارسال خروجی به console استفاده شود.
public EntitiesContext() : base("name=Entities") { Database.Log = Console.WriteLine; }
کد زیر خروجی ورود به SQL توسط کد بالا می باشد:
- C#.net
- 3k بازدید
- 6 تشکر