none
Ajax GridView Sayfalama, Arama, Buton Ekleme RRS feed

  • Genel Tartışma

  • Merhaba,

    Öncelikle yeni başlayan bir programcıyım..

    Büyük verileri olan tablolarda direkt olarak gridviewe göndermek hız kaybı olduğundan sayfalamayı kendim yapmaya çalışıyorum.

    Bir stored procedure ile hem arama filtreleme hem de kayıt sayısı ve sayfa numarası göndererek sadece görmek istediğim sayfa verilerini çekmiş oldum.

    Sayfanın tamamen refresh olmasını istemediğimden 2. aşamada ajax ile c# webmethod kullanarak gridviewi doldurdum.

    Ajax için static metot kullanmak zorunda olduğumdan sayfalama butonlarını kullanmak için sayfa numarasını sessionda yakaladım, (session kullanımını keşfetmem de uzun vakit almıştı)

    Ajax kullanıcı tarafında çalıştığından her kodlamayı javascript ile yapmak durumunda kalıyorum, javascript hiç anlamasamda bulduğum kodları uyarlayarak bu seviyeye kadar geldim.

    şimdi gride düzenle, sil butonları eklemem gerek ancak sanırım bunu da javascript ile kodlamam gerekecek.

    birde css srounları oluyor adminlte temayı kullanarak öğrenmeye çalışıyorum, ajax ile yaptığım gridi class versemde tanımıyor.

    1. bu işlemi nasıl yapabilirim?

    2. doğru yolda mıyım? daha kolay bir yolu var da ben mi zorlaştırıyorum?

    hazır gridleri kullansam bu kez de tüm datayı bağlamak hız kaybına sebep oluyor. bu işin temiz çözümü nedir sizce?

    gridi bind eden script aşağıdaki gibi, ben kendime uyarladım 2 tane de parametre gönderdim metoda

    https://www.codeproject.com/tips/775585/bind-gridview-using-ajax


    yardımlarınızı rica ederim

    14 Aralık 2016 Çarşamba 13:46

Tüm Yanıtlar

  • Büyük veri derken ortalama ne kadar kaydı kastediyorsunuz?

    Sayfa numaralarını session'da saklamanıza gerek yok.

    Sayfalama için kullandığınız procedure nasıl?

    Ajax ile gridi yaparken class tanımlamasını yaparsanız çalışması lazım. Kod olmadığı için bir şey diyemeyeceğim. 


    http://pgnchess.com
    http://dergikapaklari.com

    14 Aralık 2016 Çarşamba 16:51
  • Buton eklemeyi başardım, onclick olayına da javascript fonksiyona bağladım, 

    Yaptığım yöntemin doğruluğunu sorguluyorum..

    Örneğin 50.000, 100.000 kayıt datasource olarak verilince sayfa viewstate'e almaya çalışıyor, bu bence performans kaybı..

    kod sayfası, sp ve asp sayfası aşağıdaki gibi

     protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack) 
                BindDummyItem(); 
            }
            public void BindDummyItem()
            {
                DataTable dtGetData = new DataTable();
                dtGetData.Columns.Add("Id");
                dtGetData.Columns.Add("Title");
                dtGetData.Columns.Add("Content");
                dtGetData.Columns.Add("Date");
                dtGetData.Rows.Add();
                GridView1.DataSource = dtGetData;
                GridView1.DataBind();

            }




            [WebMethod(EnableSession = true)]
            public static Articles[] GetData(string filtre, string sayfa) //GetData function
            {

                int sayfaSayisi;

                //if (sayfa.ToString() == "undefined" || sayfa == null || sayfa == "" || sayfa == "0")
                if (sayfa == "" || sayfa == "0")
                    HttpContext.Current.Session["Page"] = 1;

                if (filtre == "")
                    filtre = "1=1";
                else
                    filtre = "Title LIKE \'%" + filtre + "%\'";


                sayfaSayisi = Convert.ToInt32(SqlTools.ExecScalarSorgu("SELECT CEILING(CONVERT(DECIMAL, COUNT(*),2)/15) AS Say FROM Articles WHERE " + filtre, CommandType.Text));

                if (sayfa == "1" && sayfaSayisi > (int)HttpContext.Current.Session["Page"])
                    HttpContext.Current.Session["Page"] = (int)HttpContext.Current.Session["Page"] + 1;


                if (sayfa == "-1" && (int)HttpContext.Current.Session["Page"] == 1)
                    HttpContext.Current.Session["Page"] = 1;
                else
                    if (sayfa == "-1")
                    HttpContext.Current.Session["Page"] = (int)HttpContext.Current.Session["Page"] - 1;

                List<Articles> Detail = new List<Articles>();

                SqlTools.ListParametreEkle("@KayitSayisi", 15);
                SqlTools.ListParametreEkle("@SayfaNumarasi", HttpContext.Current.Session["Page"]);
                SqlTools.ListParametreEkle("@TabloAdi", "Articles");
                SqlTools.ListParametreEkle("@Filtre", filtre);

                DataTable dtGetData = SqlTools.SelectSp("SpPaging");

                foreach (DataRow dtRow in dtGetData.Rows)
                {
                    Articles Article = new Articles();
                    Article.Id = Convert.ToInt32(dtRow["Id"]);
                    Article.Title = dtRow["Title"].ToString();
                    Article.Content = dtRow["Content"].ToString();
                    Article.Date =(dtRow["Date"]!= DBNull.Value) ? Convert.ToDateTime(dtRow["Date"]) : (DateTime?)null;

                    Detail.Add(Article);
                }


                return Detail.ToArray();
            }

    Asp:

    <script type="text/javascript">
    function stopRKey(evt) {
    var evt = (evt) ? evt : ((event) ? event : null);
    var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
    if ((evt.keyCode == 13) && (node.type=="text"))  {
    return false;
    }
    }
    document.onkeypress = stopRKey;
    </script>


    <script>

    function SearchClick(e) { 
        if (e.keyCode == 13) {
        document.getElementById('ContentMain_hdnSayfa').value = 0;
        BindGridView();
        return false;
        } 


    function NextPage() {
        document.getElementById('ContentMain_hdnSayfa').value = 1;
        BindGridView();
        return false;
    }

    function PrevPage() {
        document.getElementById('ContentMain_hdnSayfa').value = -1;
        BindGridView();
        return false;
    }

    </script>

    <script src="/Content/Admin/plugins/jQuery/jquery-2.2.3.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            BindGridView();
            
    });
    </script>


    <script>
        function ConvertJsonDateString(jsonDate) {
            var shortDate = null;

            if (jsonDate) {
                var regex = /-?\d+/;
                var matches = regex.exec(jsonDate);
                var dt = new Date(parseInt(matches[0]));
                var month = dt.getMonth() + 1;
                var monthString = month > 9 ? month : '0' + month;
                var day = dt.getDate();
                var dayString = day > 9 ? day : '0' + day;
                var year = dt.getFullYear();
                shortDate = dayString + '/' + monthString + '/' + year;
            }

            return shortDate;
        };
    </script>


    <script>
        function BindGridView() {
    $.ajax({
                type: "POST",
                url: "ArticleAjax.aspx/GetData",
                contentType: "application/json;charset=utf-8",
                //data: {},
                data: '{ "filtre":"' + escape($('#txtSearch').val()) + '","sayfa":"' + document.getElementById('ContentMain_hdnSayfa').value + '" }',
                dataType: "json",
                success: function (data) {

                    $("#ContentMain_GridView1").empty();
                    if (data.d.length > 0) {
                        $("#ContentMain_GridView1").append("<tr>   <th>Id</th> <th>Title</th> <th>Content</th> <th>Date</th> <th></th> </tr>");
                        for (var i = 0; i < data.d.length; i++) {
                            $("#ContentMain_GridView1").append("<tr><td>" +
                            data.d[i].Id + "</td> <td>" +
                            data.d[i].Title + "</td> <td>" +
                            data.d[i].Content + "</td> <td>" +
                            ConvertJsonDateString(data.d[i].Date) + "</td> <td>" +
                            "<a onclick=\"NextPage(); return false;\" class=\"btn btn-primary btn-sm\" ><i class=\"fa fa-edit\"></i></a>   " +
                            "<a onclick=\"NextPage(); return false;\" class=\"btn btn-danger btn-sm\" ><i class=\"fa fa-trash\"></i></a>" + "</td> </tr>");
                            
                        }
                    }
                },
                error: function (result) {
                    //alert("Error login");
                }
          });
    }
    </script>

    ALTER PROCEDURE [dbo].[SpPaging]
    @KayitSayisi INT,
    @SayfaNumarasi INT,
    @TabloAdi NVARCHAR(50),
    @Filtre NVARCHAR(500)
    AS
    SET NOCOUNT ON;
    DECLARE @SqlCmd NVARCHAR(2000)
    DECLARE @BaslangicID INT,@BitisID INT
    SET @BaslangicID=((@SayfaNumarasi -1)*@KayitSayisi)+1
    SET @BitisID=(@BaslangicID+@KayitSayisi)-1

    SET @SqlCmd = ';WITH NumberedRows AS 
    (SELECT * ,Row_Number() OVER (ORDER BY Id DESC) AS RowNumber FROM '+@TabloAdi+ ' WHERE ' + @Filtre +') 
    SELECT * FROM NumberedRows WHERE RowNumber BETWEEN ' + CONVERT(NVARCHAR(10),@BaslangicID) + ' AND ' + CONVERT(NVARCHAR(10),@BitisID) +' ORDER BY Id DESC'


    --print @SqlCmd


    Exec sp_executesql @SqlCmd


    Hayat tercihlerden ibarettir..

    14 Aralık 2016 Çarşamba 17:28
  • Şu an çok fazla zamanım yok. Kısaca bir baktım

    1. Sayfalama yaparak kazandığınız bütün zamanı tek bir satırda harcıyorsunuz.

      sayfaSayisi = Convert.ToInt32(SqlTools.ExecScalarSorgu("SELECT CEILING(CONVERT(DECIMAL, COUNT(*),2)/15) AS Say FROM Articles WHERE " + filtre, CommandType.Text));

    direk Count en yavaş çalışan sayma yöntemidir. Hele bir de buna Like %deger% gibi bir koşul eklerseniz. Kazanmaya çalıştığınız bütün performans bu satırla kayboluyor. Bir de bu satırı siz her çağırmada hesaplatıyorsunuz. Yani filtre çalıştı 20 sayfa var diyelim. Kullanıcı 1'den 2. sayfaya geçerken sayfa sayısı değişmiyor ama siz bir daha hesaplatıyorsunuz. Kısacası şartlar değişmedikçe hesaplama yaptırmayın. Filtre için dallanmaya gidin örneğin kullanıcıya sorun ile başlayanlar, ile bitenler, içinde geçenler gibi. Like'i ona göre oluşturun.

    2. Sayfalama yöntemi de yavaş gibi. Aynı sorguyu FETCH yöntemi ile de bir deneyin derim.



    http://pgnchess.com
    http://dergikapaklari.com

    14 Aralık 2016 Çarşamba 17:48
  • Esasında SP konusunda bir problemim yok, 

    fetch yapılacak bir durum da yok, zaten sorgu tüm kayıtlar içinde hangi sayfayı istiyorsam sadece o sayfayı getiriyor, tüm tabloyu sayfalara ayırmıyor, sayfanın başlangıç ve bitiş sırasına göre sorguluyor (ROW NUMBER)

    şu an arama veya sonraki sayfaya geçiş anlık yapılabiliyor.

    asp gridview'e tüm datayı bağlarsam, sayfa her açılışta tüm veriyi çekmek zorunda kalıyor, benim yaptığım yöntemde en fazla 1 sayfalık veri çekiyorum, (20, 50, 100 kayıt gibi).

    Ben hem hızlı veri çekme hem de sayfayı sürekli post etmek yerine ajax ile controllere veri bağlamayı hedefliyorum.

    Bu işlemlerin profesyonel çözümlerini öğrenmeye çalışıyorum.


    Hayat tercihlerden ibarettir..


    14 Aralık 2016 Çarşamba 18:52
  • Cemalettin bey, profesyonel kelimesinden ne kastettiğinizi bilmiyorum, ben "işi para alarak yapan kişi" diye biliyorum. Eğer "doğru, kitabına uygun iş anlamında" kullandıysanız yukarıda yazdıklarınızın çok daha profesyonelce olanları var. Çok basit işler için inanılmaz fazla kod yazıyorsunuz. 

    Bilgi olsun diye söylüyorum; jquery, knockoutjs, entityfarmework gibi şeyler kullanarak yapmak istediğiniz şey 5-6 satırdan ibaret, haberiniz olsun.


    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    14 Aralık 2016 Çarşamba 19:20
    Moderatör
  • Önay Bey,

    Para ile ilgisini anlamadım, 2 ay önce öğrenmeye başladım ve günde 1 saat zaman ayırarak öğrenmeye çalışan biriyim sadece.

    Temelden öğrenmek istediğim için ado.net kullanmadan direkt entity framework kullanmak istemedim, entity frameworku de inceledim bir kaç örnek de yaptım. zamanı gelince onu da kullanacağım.

    asp.net ilk kez kullanıyorum sadece asp.net yaparsam 5 6 satır kodla sayfalama arama yaptım zaten, ama ajax kullanmadan sayfanın sürekli post olmasını engelleyemedim veya 100.000 adet veriyi hızlı sayfalama yapamadım javascript kullanma ihtiyacı hissettim, ihtiyaç oldukça her konuyu öğrenmeye başladım.

    asp.nette biraz örnek yaptıktan sonra da mvc öğrenmeyi hedefliyorum.

    devexpress veya jqgrid gibi componentler kullanmak istemedim kendim birşeyler yapabilmeyi hedefliyorum. 

    "5 6 satırdan ibaret" olabilir ben aksini iddia etmiyorum zaten, hatta 5 6 satırla nasıl yapıldığından bahsederseniz çok iyi olurdu ben de bunu öğrenmeye çalışıyorum.

    mesela hangi kodlar fazla? bilgi verirseniz benim için çok faydalı olacaktır.

    Store procedure 1 kez yazdım, tablo ismi bile parametrik, her tabloda kullanabileceğim.

    gridi bind eden javascript kodları asp gridview template kullanmaktan daha uzun değil, Tablomu class olarak tanımladım, entitiy framework te aynı şekilde her tabloya bir class oluşturuyor. ado için gerekli parametreleri yükledim, kendi data access layerimden sonuç dönüyor katmanlı yapıyı da kullandım.

    geriye kullanıcı tarafındaki javascript kodları kalıyor, bunları da sayfayı post etmemek için kullandım ki başka yolu varsa öğrenmeyi çok isterim.

    sorumun en başında "Öncelikle yeni başlayan bir programcıyım.." şeklinde belirtmiştim yani amaç öğrenmek..



    Hayat tercihlerden ibarettir..


    14 Aralık 2016 Çarşamba 19:59
  • Lütfen beni yanlış anlamayın, sizi işin doğrusunun ne olduğu konusunda araştırmaya yöneltmek istemiştim, siz zaten bunu yapmışsınız. 5-6 satırda nasıl yapıldığını bende anlatmak isterim ama malesef forumda bunu yapmak zor.

    Aşağıdaki örnek sonsuz kategori ağacını mvvm ile nasıl uygulandığı ile ilgili. Yazdıklarınız ile karşılaştırıp ne demek istediğimi anlatabilir belki;

    @model IEnumerable<Category>
    @{
        ViewBag.Title = "Kategori Yönetimi";
        ViewBag.Descriptions = "Ürün kategorileri yönetim sayfası.";
    }
    
    <div data-bind="template: { name: 'categoryTreeNodeTemplate', data: $data }" class="tree"></div>
    
    @functions{
        HtmlString GetCategories()
        {
            return new HtmlString(Json.Encode(GetSubCategories()));
        }
    
        List<dynamic> GetSubCategories(int? Id = null)
        {
            var list = new List<dynamic>();
            foreach (var item in Model.Where(p => p.ParentId == Id))
                list.Add(new { @Id = item.Id, @Name = item.Name, Children = GetSubCategories(item.Id) });
            return list;
        }
    }
    
    @section scripts{
        <script src="~/Scripts/knockout-3.4.0.js"></script>
        <script>
            $(function () {
                var viewModel = { "Id": -1, "Name" : "Ana Dizin", "Children": @GetCategories()};
                ko.applyBindings(viewModel);
    
                $('.tree-item').hover(
                    function(){
                        $(this).children('.tree-button-group').fadeIn(100);
                        $(this).children('.tree-label').addClass('active');
                    },
                    function(){
                        $(this).children('.tree-button-group').fadeOut(100);
                        $(this).children('.tree-label').removeClass('active');
                    });
            })
        </script>
        <script id="categoryTreeNodeTemplate" type="text/html">
            <ul>
                <li>
                    <div class="tree-item">
                        <span class="tree-label"  data-bind="text: Name"></span>
                        <span class="tree-button-group">
                            <i class="fa fa-fw fa-plus text-success"></i>
                            <i class="fa fa-fw fa-pencil text-warning"></i>
                            <i class="fa fa-fw fa-remove text-danger"></i>
                        </span>
                    </div>
                    <br />
                    <!-- ko template: { name: 'categoryTreeNodeTemplate', foreach: Children } -->
                    <!-- /ko -->
                </li>
            </ul>
        </script>
    }

      

    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    14 Aralık 2016 Çarşamba 20:34
    Moderatör
  • Rica ederim, demek istediğinizi anladım, ben de hem araştırma hem de optimum çözümleri keşfetme sürecindeyim.

    Buton altı kod yazan veya algoritmadan, analizden anlamayan o kadar çok yazılımcı var ki...

    İlk kategori örneğimde bende sonsuz kategoriyi yapmıştım, recursive yöntemle bir metot yazmıştım, mvvm  yi ilk kez duydum bir ara bunu da araştıracağım.

    İlginiz için teşekkür ederim..

     public class Utility
        {

            DataTable dtr = new DataTable();

            public Utility()
            {
                //// create fields
                dtr.Columns.Add("id", typeof(int));
                dtr.Columns.Add("parentid", typeof(int));
                dtr.Columns.Add("name", typeof(string));
                dtr.Columns.Add("level", typeof(string));
            }

            internal DataTable KategoriGetir(DataTable dt)
            {
                KategoriSirala(dt, 0, 0);

                return dtr;
            }

            void KategoriSirala(DataTable dt, int ParentId, int seviye)
            {

                DataRow[] dr;
                seviye++;
                dr = dt.Select("ParentId = " + ParentId);
                string simge;
                int parentid;
                int id;
                for (int i = 0; i < dr.Length; i++)
                {
                    id = (int)dr[i]["ParentId"];
                    parentid = (int)dr[i]["Id"];
                    simge = new string('-', seviye);

                    
                    dtr.Rows.Add(new Object[]{

                                dr[i]["Id"],
                                dr[i]["ParentId"],
                                dr[i]["Name"],
                                simge+dr[i]["Name"]
                    });

                    KategoriSirala(dt, parentid, seviye);
                }

            }
        }


    Hayat tercihlerden ibarettir..

    14 Aralık 2016 Çarşamba 21:23
  • Buton altı kod yazan veya algoritmadan, analizden anlamayan o kadar çok yazılımcı var ki...

    Hemde nasıl çok...


    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    15 Aralık 2016 Perşembe 09:01
    Moderatör