Kendo UI ile Nhibernate’i Birlikte Kullanmak

Bu yazımız, Telerik firmasının çıkarmış olduğu ürünlerden bir tanesi olan kendo ui javascript kütüphanesinin, nhibernate, daha doğrusu fluent nhibernate ile birlikte kullanımı hakkında olacaktır.

Kendo UI farklı server teknolojileri ile birlikte çalışabilecek şekilde, kullanıcı arayüzü oluşturmak için hazırlanmış bir kütüphane. Benzer javascript kütüphaneleri halihazırda var, örneğin, açık kaynak kodlu, MIT lisansına sahip Jquery UI, başka bir firmanın ürünü olan Wijmo kütüphanesi, vb …

Kendo UI, görselliği ve işlevselliğiyle öne çıkan kütüphanelerden birisi. Kendo UI’ı tercih sebebi yapan pek çok faktör var. Bunlardan birisi, bir web uygulamasında ihtiyacınız olabilecek, tüm widget’ların içerisinde bulunması: düğme, diyalog, tab, grid, tree, menu vs… Öbür türlü jquery pluginlerini teker teker internetten araştırıp, uygulamanıza entegre etmeniz gerekiyor. Diğer bir sebebide, kendo ui içerisinde bulunan widgetlerin, işlevselliği ve görselliğinin tatmin edici bir düzeyde olması. Örneğin Grid widget’inda, sıralama, filtreleme ve gruplama özelliklerinin olması, verilerinin ajax çağrılarıyla getirilmesi, hızlı olması.

Şimdi Kendo Ui Grid bileşeninin, fluent nhibernate ile nasıl çalışabileceğini gösteren basit, giriş düzeyinde bir örnek hazırlayacağız. Asp.net mvc 4 web uygulamasında bu işi yapacağız. Kendo Ui’nin asp.net mvc extension’ı var, fakat ben bunu kullanmayacağım. Aspx dosyasında tamamen javascript kullanarak, grid bileşenini tanımlayacağım. Visual Studio 2010 veya 2012’yı kullanabilirsiniz. Ben Visual studio 2010 kullanacağım.

Öncelikle visual studio’yu başlatalım. New project diyerek, ASP.NET MVC 4 Web Application projesi oluşturuyoruz. kendouifluentnh ismini yazıyorum. Proje Template’ı olarak Basic, View Engine olarak Razor seçiyorum.

Projemiz oluşturulduktan sonra, ilk olarak Controller dizinine sağ tıklayarak, add Controller diyoruz. İsim olarak GridController diyebiliriz. Otomatik olarak oluşan, Index metodunun içerisine sağ tıklarak, Add View diyelim. Add View diyalog ekranında Use Layout or master page kısmını uncheck edelim. Bu sayfa için, bir layout veya master page kullanmasın istiyoruz.

Şimdi F5 dediğimizde bu sayfanın otomatik olarak gelmesi için, RouteConfig.cs dosyasında değişiklik yapıyoruz. controller’ı Grid olarak değiştiriyoruz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
 
namespace kendouifluentnh
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Grid", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
}

Bu aşamada, kendo ui’ı install etmemiz gerekiyor. Visual Studio menüsünden Tools/Library Package Manager/Manage NuGet Packages For Solution… tıklayarak Package manager ekranını açıyoruz. Online kısmını seçerek, sağ üst köşeye kendo yazdığımızda, aşağıdaki listeye KendoUIWebpaketi gelecek. Bu paketi install ediyoruz. Daha sonra aynı şekilde Fluent diyerek aratıyoruz. Gelen listeden Fluent NHibernate paketini install ediyoruz.

Index.cshtml dosyasını aşağıdaki gibi değiştiriyoruz, kendo linklerinde, versiyon numarasına göre (örn: 2012.3.1114) değişiklik olabilir, buna dikkat edilmeli. Siz kendi kurduğunuz kendo ui versiyonuna göre değiştirmelisiniz.

@{
    Layout = null;
}
 
<!DOCTYPE html> 
 
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <link href="../../Content/kendo/2012.3.1114/kendo.common.min.css" rel="stylesheet" type="text/css" />
    <link href="../../Content/kendo/2012.3.1114/kendo.default.min.css" rel="stylesheet" type="text/css" />
    <style type="text/css">
        html {
            font: 75% Arial,Helvetica,sans-serif;
        }
    </style>
    <script src="../../Scripts/kendo/2012.3.1114/jquery.min.js" type="text/javascript"></script>
    <script src="../../Scripts/kendo/2012.3.1114/kendo.web.min.js" type="text/javascript"></script>
</head>
<body>
    <!-- Define the HTML div that will hold the Grid -->
    <div id="grid">
 
    </div>
    <script type="text/javascript">
        $("#grid").kendoGrid({
            filterable: true,
            columns: [  
                        {
                            field: "Id",
                            filterable: false
                        },
                        "Ad",
                        {
                            field: "Soyad",
                            title: "Soyad",
                            width: 200
                        },
                        "Yas"   
            ],
            dataSource: {
                type: "json",
                transport: {
                    read: {
                        url: '@Url.Action("Sonuclar")',
                        dataType: "json",
                        type: "POST",
                        contentType: "application/json; charset=utf-8"
                    },
                    parameterMap: function (options) {
                        return JSON.stringify(options);
                    }
                },
                schema: {
                    model: {
                        fields: {
                            Id: { type: "number" },
                            Ad: { type: "string" },
                            Soyad: { type: "string" },
                            Yas: { type: "number" }
                        }
                    }
                },
                serverFiltering: true,
                serverSorting: true
            }
        });
    </script>
</body>
</html>

Şimdide model dizinine iki sınıf tanımlıyoruz. Sort ve Filter sınıfları. Bu sınıfları gridden gelen parametreleri, action methodunda bind ederken kullanacağız.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace kendouifluentnh.Models
{
    public class Filter
    {
        public string Field { get; set; }
 
        public string Operator { get; set; }
 
        public object Value { get; set; }
 
        public string Logic { get; set; }
 
        public IEnumerable<Filter> Filters { get; set; }
 
        private static readonly IDictionary<string, string> operators = new Dictionary<string, string>
        {
            {"eq", "="},
            {"neq", "!="},
            {"lt", "<"},
            {"lte", "<="},
            {"gt", ">"},
            {"gte", ">="},
            {"startswith", "StartsWith"},
            {"endswith", "EndsWith"},
            {"contains", "Contains"}
        };
 
        public IList<Filter> All()
        {
            var filters = new List<Filter>();
 
            Collect(filters);
 
            return filters;
        }
 
        private void Collect(IList<Filter> filters)
        {
            if (Filters != null && Filters.Any())
            {
                foreach (Filter filter in Filters)
                {
                    filters.Add(filter);
 
                    filter.Collect(filters);
                }
            }
            else
            {
                filters.Add(this);
            }
        }
 
        public string ToExpression(IList<Filter> filters)
        {
            if (Filters != null && Filters.Any())
            {
                return "(" + String.Join(" " + Logic + " ", Filters.Select(filter => filter.ToExpression(filters)).ToArray()) + ")";
            }
 
            string comparison = operators[Operator];
 
            if (comparison == "StartsWith")
            {
                return String.Format("{0} like '{1}%'", Field, Value);
            }
 
            if (comparison == "EndsWith")
            {
                return String.Format("{0} like '%{1}'", Field, Value);
            }
 
            if (comparison == "Contains")
            {
                return String.Format("{0} like '%{1}%'", Field, Value);
            }
 
            return String.Format("{0} {1} '{2}'", Field, comparison, this.Value);
        }
    }
}

Sort sınıfı:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace kendouifluentnh.Models
{
    public class Sort
    {
        public string field { get; set; }
 
        public string dir { get; set; }
    }
}

POCO objesi olarak Personel (Personel.cs) sınıfımızı oluşturuyoruz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace kendouifluentnh.Models
{
    public class Personel
    {
        public virtual long Id { get; set; }
        public virtual string Ad { get; set; }
        public virtual string Soyad { get; set; }
        public virtual int Yas { get; set; }
    }
}

Fluent NHibernate kullanacağımız için bir map dosyası (PersonelMap.cs) tanımlıyoruz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
 
namespace kendouifluentnh.Models
{
    using FluentNHibernate.Mapping;
 
    public class PersonelMap : ClassMap<Personel>
    {
        public PersonelMap()
        {
            Table("PERSONEL");
            Id(x => x.Id).Column("ID");
            Map(x => x.Ad).Column("AD");
            Map(x => x.Soyad).Column("SOYAD");
            Map(x => x.Yas).Column("YAS");
        }
    }
}

Bu örnekte database olarak, oracle kullanıyoruz. Programımız için, erişim hakkımızın olduğu bir oracle veritabanı olmalı. İçerisinde PERSONEL tablosu olmalı. Bu tabloyu fluent nhibernate kullanarak Personel objesine bağlayacağız. Aşağıdaki sql scripti kullanarak Oracle’da tabloyu oluşturabilirsiniz.

CREATE TABLE PERSONEL 
(  
 "ID" NUMBER(20,0), 
 "AD" VARCHAR2(50 BYTE), 
 "SOYAD" VARCHAR2(50 BYTE), 
 "YAS" NUMBER(20,0) 
)

Global.asax.cs dosyasında, fluent nhibernate ile Oracle veritabanı ayarlarımızı yapmamız gerekiyor. connString’i sizin veritabanı ayarlarınıza göre değiştirmeniz gerekiyor.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
 
namespace kendouifluentnh
{
    using System.Reflection;
 
    using FluentNHibernate.Cfg;
    using FluentNHibernate.Cfg.Db;
 
    using NHibernate;
 
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801
 
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
 
            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
 
        public static ISessionFactory SessionFactory = CreateSessionFactory();
 
        private static ISessionFactory CreateSessionFactory()
        {
            string connString = "DATA SOURCE=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = dbip)(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = DEVERP)));PERSIST SECURITY INFO=True;USER ID=myuser;Password=mypass";
 
            var cfg = OracleClientConfiguration.Oracle10.ConnectionString(c => c.Is(connString));
 
            var fluentCfg = Fluently.Configure().Database(cfg)
                    .Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()));
 
            return fluentCfg.BuildSessionFactory();
        }
    }
}

Son olarak GridController.cs dosyamızı değiştirelim.

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
 
namespace kendouifluentnh.Controllers
{
    using kendouifluentnh.Models;
 
    public class GridController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
 
        [HttpPost]
        public JsonResult Sonuclar(List<Sort> sort, Filter filter)
        {
            var session = MvcApplication.SessionFactory.OpenSession();
 
            var stmt = "from Personel";
 
            var orderByStmt = "";
 
            if ((filter != null) && (filter.Field != null || (filter.Filters != null)))
            {
                var filterStmt = filter.ToExpression((List<Filter>)filter.Filters);
                stmt = stmt + " where " + filterStmt;
            }
 
            if (sort != null)
            {
                orderByStmt = sort.Aggregate(orderByStmt, (current, sortVar) => current == "" ? sortVar.field + " " + sortVar.dir : ", " + sortVar.field + " " + sortVar.dir);
                stmt = stmt + " order by " + orderByStmt;
            }
 
            var query = session.CreateQuery(stmt);
 
            var sonuclar = query.List<Personel>();
 
            return Json(sonuclar);
        }
    }
}

Veritabanındaki PERSONEL tablosuna dilediğimiz kadar kayıt ekliyoruz. Artık programımızı çalıştırarak, gridimizi deneyebiliriz. Böylece, kolonlara tıklayarak sıralama ve filtreleme yapabileceğimiz şekilde Kendo Ui Grid bileşenini kullanmış olduk. Bu özelliklerin dışında, son kullanıcıların ihtiyaç duyabileceği daha pekçok özelliği var. Sitesindeki demolara bakarak, neler yapabileceğini öğrenebilirsiniz.

Proje Dosyası

Yorum bırakın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Scroll to Top