EF Core İle Trigger ve Stored Procedure Yönetimi

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;

An error has occurred. This application may no longer respond until reloaded. Reload 🗙