EF Core İle Trigger ve Stored Procedure Yönetimi
Testlerimizi MySQL kullanarak gerçekleştirdik.
Mevcut Triggerlarınızı listelemek için aşağıdaki komutu kullanabilirsiniz.
select * from information_schema.TRIGGERS
Mevcut Stored Procedure'leri listelemek için aşağıdaki komutu kullanabilirsiniz.
select * from information_schema.ROUTINES
Burada veritabanınızda aktif olan scriptleriniz bulunmaktadır. Bazıları varsayılan olarak oluşturulmuştur ve sistem ihtiyaçlarınız için kullanılmaktadır. Aşağıdaki sorguları sadece sizin oluşturduğunuz scriptleri filtrelemek için genişletebilirsiniz.
select * from information_schema.TRIGGERS where TRIGGER_SCHEMA = 'your_schema'
select * from information_schema.ROUTINES where ROUTINE_TYPE = 'PROCEDURE' and ROUTINE_SCHEMA = 'your_schema'
Verilerimizi nasıl filtreleyeceğimizi gördünüz. Eğer ileride bu kısımlarda değişiklik yaptığında eski scriptlerin yenilenmesini istiyorsanız sizin için bir trick geliştirdim. Bu işlemi bir methoda koyup daha sonra Startup.cs'de public void Configure(IApplicationBuilder app) methodu içerisinde tetikleyebilirsiniz. Böylelikle proje her ayağa kalktığında eski olan scriptleri yenileriyle değiştirecektir. Bu tetikleme ihtiyacınızı projenin risk durumuna göre dikkatli değerlendiriniz!
var listTriggers = new List<string>();
var listStoredProcedures = new List<string>();
using (var command = _context.Database.GetDbConnection().CreateCommand())
{
command.CommandText = "select group_concat(TRIGGER_NAME) from information_schema.TRIGGERS where TRIGGER_SCHEMA = 'your_schema'";
command.CommandType = CommandType.Text;
_context.Database.OpenConnection();
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var value = reader[0].ToString();
if (!string.IsNullOrEmpty(value))
listTriggers.AddRange(value.Split(","));
}
}
command.CommandText = "select group_concat(ROUTINE_NAME) from information_schema.ROUTINES where ROUTINE_TYPE = 'PROCEDURE' and ROUTINE_SCHEMA = 'your_schema'";
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var value = reader[0].ToString();
if (!string.IsNullOrEmpty(value))
listStoredProcedures.AddRange(value.Split(","));
}
}
}
foreach (var item in listTriggers)
_context.Database.ExecuteSqlRaw($"drop trigger if exists {item}");
foreach (var item in listStoredProcedures)
_context.Database.ExecuteSqlRaw($"drop procedure if exists {item}");
var sqlFiles = new List<string> {"fnc", "stp", "trg"};
foreach (var sqlFile in sqlFiles)
{
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Scripts", $"{sqlFile}.sql");
var sql = File.ReadAllText(path);
if (!string.IsNullOrEmpty(sql))
_context.Database.ExecuteSqlRaw(sql);
}
Son olarak ben Scripts klasörü altına Functions (fnc.sql)/Stored Procedure (stp.sql)/Trigger (trg.sql) ayrı klasörlerde gruplayarak ekledim. Yukarıdaki kod bloğu çalıştığında filtrelere uyan tüm stored procedure ve triggerlar silinecektir ve Scripts klasörü altındaki sorgular tekrar çalışıp yüklenecektir.
Örnek olarak trg.sql dosyasının içeriği
create trigger trg_blogpost_view_count_after_update_user
after update
on blog_posts
for each row
begin
if (OLD.ViewCount + 1 = NEW.ViewCount) then
update users set BlogPostViewCount = BlogPostViewCount + 1 where Guid = OLD.CreatedBy;
end if;
end;