Saturday, December 16, 2017

ProjectBase kütüphanesi ile evrensel (global) parametre kullanımı

ProjectBase (PB) v2.5.0 ile birçok QueryGenerator (QG) sıkıntısı çözüldü ve global parametre özelliği kütüphaneye eklendi. Eski usülde parametre kullanımları eğer veri tabanı bağımsız tanımlanmak isteniyorsa FilterText özelliği içinde verilmeliydi. Bu yöntemde eğer parametre karakteri veri tabanı ile uyumsuz ise değiştiriliyordu. Bu yöntem lokal parametre kullanımı olarak tanımlanmaktadır. Global parametre kullanımında parametre SelectText, FilterText veya SelectTail içinde kullanılabilmektedir. Bu özellik ayrıca karmaşık sql komutlarının parametrik olarak QG tarafından işlenebilmesine de olanak sağlamaktadır. Aşağıdaki örneği inceleyelim:

var db = DatabaseFactory.GetDbObject();
var gen = QueryGeneratorFactory.GetDbObject(ParameterMode.Global);

string sql = @"
               select * from employees e
                            
               where e.employee_id =
 
               (select max(employee_id) from employees 
                where salary > .p.SALARY and commission_pct > .p.COMMISSION)
              ";

gen.SelectText = sql;
gen.AddFilterParameter("SALARY", 8000);
gen.AddFilterParameter("COMMISSION", 0.1d);

var dt = db.ExecuteQueryDataTable(gen.GetSelectCommandBasic());

Burada karmaşıklığı artırmak için iç içe select cümlecikleri kullandık ve iç cümleciğe parametrik olarak bir değer gönderdik. Global parametre tanımında parametre tanımlaması ".p." prefiksi kullanılarak yapılmaktadır. Örnekte gösterildiği gibi "SALARY" isimli parametre ".p.SALARY" olarak tanımlanmıştır. Neden ".p." gibi bir şey prefiks olarak tercih edildi diye soracak arkadaşlar için burada karmaşık bir derleyiciye sahip olmadığımız için örüntü (pattern) olarak yazılabilecek sql cümlecikleri içinde en az denk gelebilecek bir yapıyı tercih etmemiz gerekiyordu diye soruyu cevaplayabilirim. Yukarıdaki kod çalıştırıldığında sonuç DataTable olarak elde edilecektir.

"Bu yazıda "Oracle Managed Provider", Oracle 11g Express Edition ve HR şeması test verileri kullanılmıştır."

 "https://github.com/vyigity/ProjectBase"

Saturday, November 11, 2017

FluentGenerator kullanarak Oracle Entity Framework 6.x sınıflarının oluşturulması - Generating Oracle Entity Framework classes with FluentGenerator

FluentGenerator (FG) Entity Framework 6.x (EF) code first örüntüsüne göre sınıfların oluşturulması için yazılmış bir masaüstü uygulamasıdır. Oluşturulan sınıflar "fluent" mimariye göre oluşturulur ve POCO ve bağlantı (mapping) sınıfları ayrı ayrı oluşturulur.

FG, ProjectBase (PB) kütüphanesini kullandığı için uygulamanın çalıştırılması için PB' nin eklenmesi ve provider ayarlamalarının yapılması gerekir. Eğer Oracle unmanaged provider kullanılıyorsa "Oracle Client" kurulmalı ve ilgili ayarlamalar yapılmalıdır.

FG ve PB'yi aşağıdaki adresten indirebilirsiniz:

https://github.com/vyigity

Test veri tabanı olarak Oracle 11g express edition ve HR şeması içinde yer alan ögeler kullanılacaktır.



FG çalıştırıldığında config ayarlamalarına göre bağlantı cümleciği arayüzde görünecektir. Cümlecik değiştirilmek istenirse istenen yeni cümlecik girilir ve "CHANGE" tuşu ile yeni cümlecik geçerli hale getirilir. Namespace ismini kendi projenize göre belirledikten sonra "DIR" tuşu ile EF sınıflarının hangi klasör içinde oluşturulacağı seçilmelidir. Capitalization kısmında sınıf isimlerinin nasıl formatlanacağı seçilebilmektedir. Bu örnekte "Pascal" kullanılacaktır. Üstte yer alan TABLE_NAME kısmında tablo ismine göre, alttaki VIEW_NAME kısmından view ismine göre arama yapılabilir.

Örnek olarak görselde de görüleceği üzere "Employees" tablosuna ilişkin sınıfları oluşturmak istiyoruz. Arama kısmına "EMPL" yazarak istediğimiz tabloya ulaştık ve yön tuşları ile tabloyu sağ tarafta yer alan grid içine alarak bu tablonun oluşturulacağını belirttik. Son olarak "GENERATE" tuşu nu kullandığımızda önceden seçtiğimiz klasör içinde sınıflar aşağıdaki gibi oluşturulacaktır:

.\Generate\Context.cs

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using YourNameSpace.Models.Mapping;

namespace YourNameSpace.Models
{
    public partial class DatabaseContext : DbContext
    {
        static DatabaseContext()
        {
            Database.SetInitializer<DatabaseContext>(null);
        }

        public DatabaseContext()
            : base("Name=Context")
        {
        }

        public DbSet<Employees> Employeess { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new EmployeesMap());
        }
    }
}

Context sınıfı EF'nin temel sınıfıdır ve FG foreign key (FK) ilişkileri oluşturmadığı için bu konuyla ilgili kodlar elden bu sınıf içine eklenmelidir. Map sınıfları "OnModelCreating" fonksiyonu içine yukarıdaki gibi eklenmeli ve DbSet tanımlaması sonraki eklentiler için elden yapılmalıdır.

.\Generate\Employees.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace YourNameSpace.Models
{
    public partial class Employees
    {
        public int EmployeeId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string PhoneNumber { get; set; }
        public DateTime HireDate { get; set; }
        public string JobId { get; set; }
        public Nullable<decimal> Salary { get; set; }
        public Nullable<decimal> CommissionPct { get; set; }
        public Nullable<int> ManagerId { get; set; }
        public Nullable<short> DepartmentId { get; set; }

    }
}

Yukarıda EF Employees POCO sınıfının nasıl göründüğü verilmiştir.

.\Generate\Mapping\EmployeesMap.cs

using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;

namespace YourNameSpace.Models.Mapping
{
    public class EmployeesMap : EntityTypeConfiguration<Employees>
    {
        public EmployeesMap()
        {
            // Primary Key
            this.HasKey(t => new { t.EmployeeId });

            // Properties
            this.Property(t => t.EmployeeId)
                .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

            this.Property(t => t.FirstName)
                .HasMaxLength(20);

            this.Property(t => t.LastName)
                .IsRequired()
                .HasMaxLength(25);

            this.Property(t => t.Email)
                .IsRequired()
                .HasMaxLength(25);

            this.Property(t => t.PhoneNumber)
                .HasMaxLength(20);

            this.Property(t => t.JobId)
                .IsRequired()
                .HasMaxLength(10);

            // Table & Column Mappings
            this.ToTable("EMPLOYEES", "HR");
            this.Property(t => t.EmployeeId).HasColumnName("EMPLOYEE_ID");
            this.Property(t => t.FirstName).HasColumnName("FIRST_NAME");
            this.Property(t => t.LastName).HasColumnName("LAST_NAME");
            this.Property(t => t.Email).HasColumnName("EMAIL");
            this.Property(t => t.PhoneNumber).HasColumnName("PHONE_NUMBER");
            this.Property(t => t.HireDate).HasColumnName("HIRE_DATE");
            this.Property(t => t.JobId).HasColumnName("JOB_ID");
            this.Property(t => t.Salary).HasColumnName("SALARY");
            this.Property(t => t.CommissionPct).HasColumnName("COMMISSION_PCT");
            this.Property(t => t.ManagerId).HasColumnName("MANAGER_ID");
            this.Property(t => t.DepartmentId).HasColumnName("DEPARTMENT_ID");
        }
    }
}

EmployeesMap sınıfı EF haritalama ve bazı validation kodlarını içeren sınıftır. Validation kodlarının burada bulunması zorunlu değildir. İstenmesi durumunda etiket (Attribute) usulü de uygulanabilir. Bütün sınıfları projenize eklediğinizde EF ile ilgili veri tabanı nesneleri üzerinde işlem yapmaya başlayabilirsiniz.

Monday, October 16, 2017

ProjectBase ile DataTable Yerine Önceden Tanımlı Nesne Kullanarak Veri Çekme (Tip Belirtimli - Typed)

Daha önceki yazılarda DataTable üzerinde veri çekme örneği yapmıştık. DataTable ile yapılan işlemler "Typed" yani belirli türlü olmadığı için kodlamayı zorlaştırmaktadır. Şimdi kendi oluşturduğumuz bir sınıfa ait nesneyi verileri tutmak için kullanacağız. Yine "EMPLOYEES" tablosunu kullanalım ve önce sınıfı aşağıdaki gibi oluşturalım:

public class EMPLOYEE
{
    public string FIRST_NAME { get; set; }
    public string LAST_NAME { get; set; }
    public decimal SALARY { get; set; }
    public DateTime? HIRE_DATE { get; set; }

}

Burada dikkat edilmesi gereken husus yazacağımız sorgudan gelecek olan sütun isimlerinin "Property" isimleri ile eşleşmesidir. Eşleme büyük-küçük harfe duyarlı değildir. Şimdi bu sınıfı kullanacak veri çekme kodlarını yazalım:

var db = DatabaseFactory.GetDbObject();
var gen = QueryGeneratorFactory.GetDbObject();

gen.SelectText = "select * from employees where employee_id < 112";

List<EMPLOYEE> employees = db.GetObjectList<EMPLOYEE>(gen.GetSelectCommandBasic());

Yukarıdaki kod çalıştırıldığında id numarası 112'den küçük kayıtları yazdığımız sınıfın bir listesi olarak elde edeceğiz.

"Bu yazıda "Oracle Managed Provider", Oracle 11g Express Edition ve HR şeması test verileri kullanılmıştır."

"https://github.com/vyigity/ProjectBase"

Sunday, October 15, 2017

ProjectBase Data Access and Utility Library - ProjectBase Veri Erişim ve Yazılım Destek Kütüphanesi

ProjectBase (PB) is a Utility and Data Access library. PB designed with a database independent interface oriented approach to ensure extentibility and reliablity. PB's codes can be changed or manipulated easily. PB can be installed with nuget package manager console:
PM> Install-Package vyigity.ProjectBase -Version 4.0.0

PB has 3 type of data access:
  • Automatic Connection Management: Using single connection object and while executing a command, connection is opened and closed automatically.
  • Manuel Connection Management: Using single connection object and connection is opened and closed by developer manually.
  • Transaction Mode: PB supports PL/SQL type code writing of transactional processes. PB creates transactions and manages them automatically.
PB currently supports Oracle (Managed-Unmanaged Provider), SQL Server databases and OleDb. PB supports MySql provider with v2.0.0 and PostgreSQL provider with v3.0.0.
Also PB supports low level object mapping features.

Project Adress:
For introduction:
For connection management examples:
For transactions examples:
For DML examples:
For parametric database procedures and functions examples:

ProjectBase ve QueryGenerator ile Veri Tabanı Prosedür İşlemleri

QueryGenerator ile veri tabanı prosedür veya fonksiyonlarına erişmek için öncelikle örnek veri tabanı fonksiyonlarını oluşturalım:

FUNCTION "GETUSERNAME" (
  "PARAM1" IN NUMBER) RETURN varchar2 IS

  RETURN_VAL varchar2(150);

BEGIN 

  select FIRST_NAME ||' ' || LAST_NAME into RETURN_VAL from employees where employee_id = PARAM1;
  
  RETURN RETURN_VAL;

END;


FUNCTION "GETSALARY" (
  "PARAM1" IN NUMBER) RETURN number IS

  RETURN_VAL NUMBER;

BEGIN 
  
  select SALARY into RETURN_VAL from employees where employee_id = PARAM1;

  RETURN RETURN_VAL;

END;

Yukarıda string değer döndüren "GETUSERNAME" ve decimal değer döndüren "GETSALARY" fonksiyonlarını oluşturduk. Aşağıda gibi bu fonksiyonları .NET projemiz içinde kullanabiliriz:

var db = DatabaseFactory.GetDbObject();
var gen = QueryGeneratorFactory.GetDbObject();

gen.ProcedureName = "GETSALARY";
gen.AddDataParameter("RETURN_VAL", DbType.Decimal, null, 150, System.Data.ParameterDirection.ReturnValue);
gen.AddDataParameter("PARAM1", 100);

db.ExecuteQuery(gen.GetProcedure());

var return_val = gen.GetParameterValue("RETURN_VAL");

string gen2 = QueryGeneratorFactory.GetDbObject();

gen2.ProcedureName = "GETUSERNAME";
gen2.AddDataParameter("RETURN_VAL", DbType.String, null, 150, System.Data.ParameterDirection.ReturnValue);
gen2.AddDataParameter("PARAM1", 100);

db.ExecuteQuery(gen2.GetProcedure());

decimal return_val2 = gen2.GetParameterValue("RETURN_VAL");

Yukarıda görüldüğü üzere QueryGenerator ile standart bir kod arayüzü ile fonksiyon ve prosedür erişimleri yapılabilmektedir.

"Bu yazıda "Oracle Managed Provider", Oracle 11g Express Edition ve HR şeması test verileri kullanılmıştır."

"https://github.com/vyigity/ProjectBase"

Saturday, October 14, 2017

ProjectBase ile QueryGenerator kullanarak parametrik DML işlemleri

"QueryGenerator" (QG) standart olarak parametrik veri tabanı işlemlerini gerçekleştirilmesi sağlayan sınıftır. Parametrik işlemler SQL injection gibi güvenlik açıklarına karşı kesinlikle tercih edilmesi gereken bir yöntemdir. Parametrik işlemlerde kullanılan ve sql texti içinde yer alan bir sözün parametre olup olmadığının anlaşılmasını sağlayan ve verita banına göre değişebilen bazı karakterler vardır. Bunlar SQL Server veri tabanı için "@", Oracle veri tabanı için ":" karakterleridir. Örneğin SQL Server içi parametre yazılacaksa "@Param" şeklinde, Oracle için yazılacaksa ":Param" şeklinde yazılır. QG sınıfı standart olarak ":Param" şeklinde yazılacak şekilde hazırlanmıştır.

Aşağıdaki kod bloku ile QG ile nasıl veri çekilebileceği gösterilmiştir:

var gen = QueryGeneratorFactory.GetDbObject();
var db = DatabaseFactory.GetDbObject();
string sql = "select * from employees where employee_id = :ID";

gen.SelectText = sql;
gen.AddFilterParameter("ID", 100);

var dt = db.ExecuteQueryDataTable(gen.GetSelectCommandBasic());

Yukarıdaki örnekte görüldüğü üzere ":ID" parametresi ile bir filterparameter oluşrulmuş ve 100 id numaralı kişinin bilgileri çekilmiştir.

QG ile Update ve Insert işlemleri de kolaylıkla yapılabilmektedir. Aşağıdaki kod bloğunda 101 id numaralı kişinin bilgileri güncellenmiştir:

var db = DatabaseFactory.GetDbObject();
var gen = QueryGeneratorFactory.GetDbObject();
gen.TableName = "EMPLOYEES";
gen.AddDataParameter("FIRST_NAME", "VELI YIGIT");
gen.AddDataParameter("LAST_NAME", "YOLCU");
gen.AddFilterParameter("Param1", 101);
gen.FilterText = "WHERE employee_id = :Param1";

db.ExecuteQuery(gen.GetUpdateCommand());

Yukarıdaki kod bloğundan anlaşıldığı üzere sadece değiştirilecek alanların parametre olarak eklenmesi yeterlidir. Gerekli update komutu QG tarafından oluşturulmaktadır. Burada dikkat edilmesi  gereken nokta filtre içinde yer alan parametreler "FilterParameter" olarak eklenmelidir.

QG ile Insert işlemi aşağıdaki gibi yapılabilmektedir:

var db = DatabaseFactory.GetDbObject();
var gen = QueryGeneratorFactory.GetDbObject();
gen.TableName = "EMPLOYEES";
gen.AddDataParameter("EMPLOYEE_ID", "300");
gen.AddDataParameter("FIRST_NAME", "VELI YIGIT");
gen.AddDataParameter("LAST_NAME", "YOLCU");
gen.AddDataParameter("EMAIL", "vyigity@deneme.com");
gen.AddDataParameter("HIRE_DATE", new DateTime(2017,10,14));
gen.AddDataParameter("JOB_ID", "SH_CLERK");

db.ExecuteQuery(gen.GetInsertCommand());

Update komutuna benzer olarak Insert komutunda da eklenecek alanların DataParameter olarak eklenmesi yeterlidir.

"Bu yazıda "Oracle Managed Provider", Oracle 11g Express Edition ve HR şeması test verileri kullanılmıştır."

"https://github.com/vyigity/ProjectBase"

Sunday, October 8, 2017

ProjectBase ile Veri Tabanı Bağlantı Türlerine Göre İşlemler

ProjectBase "TransactionMode" dışında bağlantı kontrolüne göre 2 yöntem içermektedir. "ManuelConnectionManagement" ile veri tabanı işlemleri şöyle yapılabilmektedir:

IDatabase2 db = DatabaseFactory.GetDbObject();
db.ExecuteQuery("update employees set salary = 3000 where employee_id = 100");

//Yeni veri tabanı bağlantısı kuruldu
//salary = 3000 oldu
//Bağlantı kesildi

db.ExecuteQuery("update employees set salary = 24000 where employee_id = 100");

//Yeni veri tabanı bağlantısı kuruldu
//salary = 24000 oldu
//Bağlantı kesildi

Yukarıdaki kod örneğinde gösterildiği üzere her işlemde bağlantı kurulup kapatılmaktadır. Art arda işlemlerde bu durum performans sorunu çıkaracağından bu durumda "ManuelConnectionManagement" tercih edilmelidir. Bu durumda aynı işlem iki farklı kod biçiminde yazılabilir.

IDatabase2 db2 = DatabaseFactory.GetDbObject(DbSettings.ManuelConnectionManagement);
db2.ExecuteQuery("update employees set salary = 3000 where employee_id = 100");

//Veritabanı bağlantısı kuruldu
//salary = 3000 oldu
//Bağlantı açık bırakıldı

db2.ExecuteQuery("update employees set salary = 24000 where employee_id = 100");

//Eski bağlantısı kullanıldı
//salary = 24000 oldu
//Bağlantı açık bırakıldı

db2.CloseConnection();

//Bağlantı kesildi.

Yukarıdaki örnekte görüldüğü üzere "CloseConnection" çağrılmadan bağlantı sonlandırılmamaktadır. Aynı kod aşağıdaki biçimde de yazılabilir:

using (IDatabase2 db = DatabaseFactory.GetDbObject(DbSettings.ManuelConnectionManagement))
{
    db.ExecuteQuery("update employees set salary = 3000 where employee_id = 100");

    //Veritabanı bağlantısı kuruldu
    //salary = 3000 oldu
    //Bağlantı açık bırakıldı

    db.ExecuteQuery("update employees set salary = 24000 where employee_id = 100");

    //Eski bağlantısı kullanıldı
    //salary = 24000 oldu
    //Bağlantı açık bırakıldı           
}

//Bağlantı kesildi.

"Bu yazıda "Oracle Managed Provider", Oracle 11g Express Edition ve HR şeması test verileri kullanılmıştır."

"https://github.com/vyigity/ProjectBase"

Saturday, October 7, 2017

ProjectBase ile Veri Tabanı İşlemleri (Transaction Örneği)

"ProjectBase" kütüphanesi otomatik transaction yönetimi ve connection yönetimi yapmaktadır. Veritabanı erişim sınıfları 3 modda çalışmaktadır. Bunlar:

* AutoConnectionManagement
* ManuelConnectionManagement
* TransactionMode

Veri tabanı erişim sınıfları ön tanımlı olarak "AutoConnectionManagement" modda çalışmaktadır. Bu modda klasik olarak her işlemde bağlantı açılıp işlem sonlandığında bağlantı kapatılmaktadır. Bu yöntem sıralı işlemlerde yavaş çalıştığından "ManuelConnectionManagement" modunda bağlantının ne zaman açılıp kapanacağı yazılımcı tarafından yönetilerek performans kazanımı yapılabilmektedir. TransactionMode ise PL/SQL tipinde kod yazımı için geliştirilmiştir.

Aşağıdaki örnekte TransactionMode kullanılarak nasıl işlem yapılacağı gösterilmiştir:

using (IDatabase2 db = DatabaseFactory.GetDbObject(DbSettings.TransactionMode))
{
    //salary = 24000

    db.ExecuteQuery("update employees set salary = 3000 where employee_id = 100 ");
    db.Commit();

    //salary = 3000 oldu

    db.ExecuteQuery("update employees set salary = 5000 where employee_id = 100 ");
    db.Commit();

    //salary = 5000 oldu

    db.ExecuteQuery("update employees set salary = 6000 where employee_id = 100 ");
    db.ExecuteQuery("update employees set manager_id = 101 where employee_id = 100 ");
    db.Commit();

    //salary = 6000 ve manager 101 oldu

    db.ExecuteQuery("update employees set salary = 10000 where employee_id = 100 ");
    db.ExecuteQuery("update employees set manager_id = null where employee_id = 100 ");
    db.RollBack();

    //salary = 6000 ve manager 101 kaldı

    db.ExecuteQuery("update employees set salary = 24000 where employee_id = 100 ");
    db.ExecuteQuery("update employees set manager_id = null where employee_id = 100 ");
    db.Commit();

    //salary = 24000 ve manager null oldu

    db.ExecuteQuery("update employees set salary = 50000 where employee_id = 100 ");

    throw new Exception("Fatal Error!");

    //Son işlem geri alındı.
}

Yukarıda görüldüğü gibi veri tabanı erişim sınıfı  transaction yönetimini otomatik olarak gerçekleştirdi. Yani yukarıdaki kod incelendiğinde 6 tane transaction otomatik olarak oluşturulmuş ve işlenmiştir. Veri tabanı erişim sınıfı ön tanımlı olarak hata olması durumunda rollback yapmaktadır. Bu yüzden son işlem geri alınmıştır.

"Bu yazıda "Oracle Managed Provider", Oracle 11g Express Edition ve HR şeması test verileri kullanılmıştır."

"https://github.com/vyigity/ProjectBase"

Veri Erişim Katmanına Giriş - Introduction to DAL (Data Access Layer)

Günümüzde yazılım projelerinde katmanlı mimari en önemli özelliklerden biridir. Katmanlı mimaride bir katman istenildiğinde başka bir projede aynen kullanılabilmekte böylece kod tekrarı azaltılmakta ve güvenilirlik büyük ölçüde artırılmaktadır.

Bir çok yazılım projesinin en önemli parçalarından biri veri erişim katmanıdır çünkü bu katman aracılığı ile veri tabanı işlemleri yürütülür. Bu yazıda kendi yazdığım "ProjectBase" (PB) isimli DAL katmanına giriş yapacağım. Proje kodlarına buradan ulaşabilirsiniz.

DAL katmanı için en önemli noktalar  tutarlılık, güvenilirlik, çok biçimlilik (Polimorfizm) ve genişletilebilirliktir. PB kütüphanesi çok biçimlilik ve genişletilebilirlik için "Interface" tabanlı bir yapıda oluşturulmuştur. PB kütüphanesi ile iş katmanında yazılan kodlarda değişiklik yapılmadan veri tabanı değişikliği kolaylıkla yapılabilmektedir. Ayrıca PB içinde tanımlı interface kullanılması ile istenildiği kadar "provider" sınıf yazılabilir ve bu sınıflar özelleştirilebilir.

Şimdi PB ile veri okuma işlemi yapalım:

* Veri tabanı olarak Oracle 11g Express Edition kullanacağım.  Veri tabanını Oracle'ın resmi sitesinden ücretsiz olarak indirebilirsiniz.

* Provider olarak Oracle "ManagedDataAccess" kullanacağım.

Veri tabanı kurulumunu yaptıktan sonra web.config içerisinde bağlantı stringi aşağıdaki gibi tanımlanmalıdır.

<connectionStrings>
      
    <add name="Context" connectionString="DATA SOURCE=XE;PASSWORD=hr;USER ID=hr" providerName="Oracle.ManagedDataAccess.Client" />
    
</connectionStrings>

Burada providerName önemlidir. Erişim sınıfları burada yazan provider bilgisine göre ilgili sınıfları seçecektir.

DAL katmanının kurulumu için "ProjectBase" kütüphanesini indirip projeye eklemek kurulum için yeterlidir.

using (IDatabase2 db = DatabaseFactory.GetDbObject())
{
    var dt = db.ExecuteQueryDataTable("select * from employees");
}

Yukarıdaki kod bloğu ile "Employees" tablosunda yer alan bütün veriler çekilip "DataTable" nesnesi olarak döndürülmektedir. Oracle veri tabanı içinde "HR" şemasında test için küçük bir veri tabanı servis edilmektedir. "Employees" tablosu bu veri tabanının içindedir.

ProjectBase kütüphanesi Oracle ve SQL veri tabanlarını ve OleDb erişimini desteklemektedir.

Saturday, September 23, 2017

Bakmak

Bana aşık bakarsan sevgim çoktur benim.
Bana yan bakarsan hiddetim çoktur benim.

Bana sıcak bakarsan muhabbetim çoktur benim.
Bana aşağı bakarsan sitemim çoktur benim.

Bana mahcup bakarsan merhametim çoktur benim.
Bana suçlu bakarsan inadım çoktur benim.

Bana korkak bakarsan cesaretim çoktur benim.
Bana gamsız bakarsan yüküm çoktur benim.

Bana hep bakarsan utancım çoktur benim.
Bana hiç bakmazsan merakım çoktur benim.

 Bana bensiz bakarsan hatıram çoktur benim.

Friday, June 23, 2017

Özgür İrade

Dünya üzerindeki her bir gerçeklik ve doğruluk izafidir. Özgür irade de bu bağlamda ancak dengi olan fakat bağı olmayan bir diğerine göre özgürdür. Kural koyucu nezdinde özgür irade, kural koyucunun olay akışına müdahale etmemesi şeklinde gerçekleşir. Zira kural koyucu iradenin ne zaman ne durumda olduğunu veya olacağını bilebilir ve eğer isterse müdahale edip değiştirebilir. Çünkü bütün olaylar, irade işleyişi de dahil olmak üzere önceden belirlenen bu kurallar dahilinde gerçekleşebilir.

Friday, April 14, 2017

Jquery ve ChartJs ile Gerçek Zamanlı Grafik Çizdirmek

Bu yazıda Jquery ve ChartJs 2.5.0 kullanarak bir web sitesi üzerinde dinamik grafik çizdireceğiz. CharJs ücretsiz bir grafik çizdirme kütüphanesi olup HTML kanvas  üzerine çizim yapmaktadır. Bu kütüphane pasta, çubuk ve çizgi gibi birçok grafik türüne destek vermektedir. Blog üzerinde hazırlanan grafik rastgele verileri çizecek olup bu uygulama dinamik döviz oranlarının gösterimi gibi amaçlarla kullanılabilir.  Grafiği çizdirebilmemiz için gerekli kanvas öğesini aşağıdaki gibi eklememiz gerekiyor:

<div style="width:400px;height:400px">

  <canvas id="myChart"></canvas>
    
</div>

Yukarıda boyutlar gelişigüzel seçilmiştir.  Sonraki aşamada gerekli javascript kodlarını aşağıdaki gibi ekleyelim.


var myChart;

var options = {

   maintainAspectRatio: false,
   responsive: true
};

var data = {

    labels: ["January", "February", "March", "April", "May", "June", "July"],

    datasets: [
        {
            label: "Buraya başlık gelecek",
            fill: true,
            lineTension: 0,
            backgroundColor: "rgba(75,192,192,0.4)",
            borderColor: "rgba(75,192,192,1)",
            borderCapStyle: 'butt',
            borderDash: [],
            borderDashOffset: 0.0,
            borderJoinStyle: 'miter',
            pointBorderColor: "rgba(75,192,192,1)",
            pointBackgroundColor: "#fff",
            pointBorderWidth: 1,
            pointHoverRadius: 1,
            pointHoverBackgroundColor: "rgba(75,192,192,1)",
            pointHoverBorderColor: "rgba(220,220,220,1)",
            pointHoverBorderWidth: 2,
            pointRadius: 1,
            data: [65, 59, 80, 81, 56, 55, 40],
            spanGaps: false                   
         }]              
};


$(document).ready(function () {

    var ctx = document.getElementById("myChart");

    myChart = new Chart(ctx, { type: 'line', data: data, options: options });
    var i = 0;

    startAnim(i);

});

function startAnim(i)
{
    setTimeout(function () {
        changeGrap(i);
    }, 500);
}

function changeGrap(i)
{
    myChart.config.data.datasets[0].data.shift();
    myChart.config.data.datasets[0].data.push(Math.random() * 100);
    myChart.update(100);

    startAnim(++i);
}

Burada data nesnesi verilerin gösterimi için gerekli değişkenleri içermektedir. Bu yazıda bunlar anlatılmayacak olup detaylı bilgiye buradan ulaşabilirsiniz. Yukarıda kodlarda options nesnesi içinde genel şekillendirme özellikleriyle ilgili bilgiler tanımlanmıştır. Bu nesne içindeki "maintainAspectRatio"  ile grafiğin görüntü oranına "aspect ratio" bağlı kalmadan taşıyıcı elementin boyutlarına genişlemesi sağlanmıştır. "responsive" özelliği taşıyıcı elementin boyunutun değişmesi drumunda grafiğin de yeniden boyutlanması amacıyla kullanılmaktadır.

"data" nesnesi içindeki "labels" dizisi ile grafiğin alt kısmının hangi etiketlerle kaç parça olacak şekilde bölümleneceği belirtilmektedir.

"datasets" dizisi içindeki ilk nesne ile grafiğimizin çizimi ile ilgili özellikler belirtilmektedir. Bu nesne içindeki "label" özelliği ile grafiğin başlığı tanımlanmaktadır. "fill" özelliği ile çizgi grafiğin çizgi altında kalan kısmın boyanması sağlanmaktadır. "data" dizisi içinde grafiğin başlangıç verisi tanımlanmaktadır (Grafiği dinamik kullanmayacaksanız grafiğin verisini tanımlamaktadır").

Jquery "ready" fonksiyonu içinde grafiğin oluşturma kodu çizgi grafik olarak (type:line) tanımlanmıştır.

"startAnim" fonksiyonu dinamik grafik güncellemesinin yapılması için kullanılmaktadır. Buradaki önemli nokta "changeGrap" fonksiyonu içindeki javascript "shift" fonksiyonu ile dizinin ilk elemanı diziden çıkarılmakta ve "push" fonksiyonu ile son eleman olarak rastgele oluşturulan yeni sayı atanmaktadır. Son olarak grafik nesnesinin (myChart) update fonksiyonu ile grafik güncellenmektedir.

Yukarıdaki kodların çalıştırılması sonucunda grafik aşağıdaki gibi oluşmaktadır: