﻿
{"id":25557,"date":"2022-09-13T18:46:38","date_gmt":"2022-09-13T18:46:38","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=25557"},"modified":"2022-09-13T18:46:38","modified_gmt":"2022-09-13T18:46:38","slug":"c-ile-row-data-gateway-design-patternrow-data-gateway-tasarim-deseni","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/c-ile-row-data-gateway-design-patternrow-data-gateway-tasarim-deseni\/","title":{"rendered":"C# \u0130le Row Data Gateway Design Pattern(Row Data Gateway Tasar\u0131m Deseni)"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde <em>Veri Katman\u0131 Modelleme Tasar\u0131m Desenleri<\/em>&#8216;nden olan Row Data Gateway pattern&#8217;\u0131n\u0131 hem teorik hem de pratik olarak inceliyor olaca\u011f\u0131z.<\/p>\n<h4>Row Data Gateway Design Pattern Nedir?<\/h4>\n<blockquote><p><em style=\"color:green;\">Row Data Gateway, bir veri kayna\u011f\u0131ndaki tek bir kayda\/sat\u0131ra\/veriye ge\u00e7it g\u00f6revi g\u00f6ren\/kar\u015f\u0131l\u0131k gelen nesnedir.<\/em><\/p><\/blockquote>\n<p>Row Data Gateway, tamamen veritaban\u0131ndaki kayd\u0131n\/verinin nesneye map edilmi\u015f halidir. \u0130htiya\u00e7 duyulan veri her ne ise, o veriye eri\u015fimle ilgili arka planda olan t\u00fcm operasyonlar geli\u015ftiriciden soyutlanarak Row Data Gateway s\u0131n\u0131f\u0131 arac\u0131l\u0131\u011f\u0131yla ger\u00e7ekle\u015ftirilir. B\u00f6ylece geli\u015ftirici direkt olarak i\u015f mant\u0131\u011f\u0131n\u0131 veritaban\u0131 sorgular\u0131na vs. bula\u015fmaks\u0131z\u0131n Row Data Gateway nesnesi \u00fczerinden y\u00fcr\u00fctebilecektir ve direkt olarak istedi\u011fi veriyi elde edip \u00e7al\u0131\u015fmalar\u0131na devam edebilecektir.<\/p>\n<h4>Row Data Gateway ile Table Data Gateway Aras\u0131ndaki Farklar Nelerdir?<\/h4>\n<p>Birka\u00e7 makale \u00f6ncesinde <a href=\"https:\/\/www.gencayyildiz.com\/blog\/c-ile-table-data-gateway-design-patterntable-data-gateway-tasarim-deseni\/\" rel=\"noopener\" target=\"_blank\">Table Data Gateway<\/a>&#8216;e dair bir inceleme i\u00e7eri\u011fi klavyeye alm\u0131\u015ft\u0131k. Row Data Gateway pattern&#8217;\u0131 deyince akl\u0131n\u0131za do\u011fal olarak Table Data Gateway pattern&#8217;\u0131 gelmi\u015f olabilir. Nihayetinde her ikisi de Veri Katman\u0131 Modelleme desenlerinden oldu\u011fu i\u00e7in teoride benzerlikler ka\u00e7\u0131n\u0131lmazd\u0131r. Hal b\u00f6yleyken <strong><em>peki bu iki pattern aras\u0131ndaki farklar nelerdir?<\/em><\/strong> sorunuzu duyar gibiyim&#8230; Gelin \u015fimdi ikisini de mukayese ederek farklar\u0131n\u0131 ortaya koyal\u0131m:<\/p>\n<table>\n<thead>\n<tr>\n<th style=\"width:50%;\">Table Data Gateway<\/th>\n<th>Row Data Gateway<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td colspan=\"2\">Row Data Gateway, tablodaki bir sat\u0131ra eri\u015fimi kaps\u00fcllerken, Table Data Gateway ise tablo d\u00fczeyinde eri\u015fimi kaps\u00fcllemektedir.<\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\">Table Data Gateway; geriye SqlDataReader gibi, DTO nesnesi gibi hem koleksiyonel hem de tekil nesnel yap\u0131lar d\u00f6nd\u00fcr\u00fcrken, Row Data Gateway ise sat\u0131r ba\u015f\u0131na bir gateway s\u0131n\u0131f\u0131 d\u00f6nd\u00fcrmektedir. Bunun i\u00e7in bir <em>Finder<\/em> s\u0131n\u0131f\u0131na ihtiya\u00e7 vard\u0131r.<\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\">Her ikisi de Transaction Script pattern&#8217;\u0131n kullan\u0131ld\u0131\u011f\u0131 yerlerde daha elveri\u015fli olaca\u011f\u0131 i\u00e7in ilgili pattern&#8217;a kar\u015f\u0131l\u0131k tercih edilmesi \u00f6nerilir.<\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\">Table Data Gateway, Row Data Gateway&#8217;e nazaran uygulama a\u00e7\u0131s\u0131ndan daha basit ve sadedir.<\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\">Table Data Gateway, genellikle bir tablo ve bir s\u0131n\u0131f olmak \u00fczere tek bir tabloya veya view&#8217;e(join sorgular\u0131 da dahil) eri\u015fmek i\u00e7in kullan\u0131lan t\u00fcm SQL&#8217;i sa\u011flamaktad\u0131r. Uygulaman\u0131n di\u011fer par\u00e7alar\u0131 veritaban\u0131yla etkile\u015fim kurmak istedi\u011fi taktirde Table Data Gateway&#8217;i kullan\u0131r. <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>Row Data Gateway \u0130\u015flevselli\u011fi Nas\u0131ld\u0131r?<\/h4>\n<p>Row Data Gateway&#8217;de sadece veriye eri\u015fim s\u00f6z konusudur. Sorgulama s\u00fcrecinde b\u00fcy\u00fckse\/k\u00fc\u00e7\u00fckse gibi condinationlara yer verilmemelidir. Olduk\u00e7a basit bir pattern oldu\u011fu i\u00e7in k\u00fc\u00e7\u00fck veya orta \u00f6l\u00e7ekli projelerde kullan\u0131lmaya \u00f6zen g\u00f6sterilebilir.<\/p>\n<p>\u0130\u015flevsel olarak Row Data Gateway, daha \u00e7ok domain katman\u0131ndaki nesneler ile veritaban\u0131ndaki veriler aras\u0131ndaki ileti\u015fimi sa\u011flayan bir tampon b\u00f6lge olarak d\u00fc\u015f\u00fcn\u00fclebilir. B\u00f6ylece veritaban\u0131 yap\u0131s\u0131 yahut sorgu mant\u0131\u011f\u0131 de\u011fi\u015fti\u011fi taktirde bu pattern sayesinde business logic&#8217;de herhangi bir de\u011fi\u015fiklik yapmam\u0131za gerek kalmaks\u0131z\u0131n do\u011fal yal\u0131t\u0131m sergilenebilmektedir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2022\/09\/C-Ile-Row-Data-Gateway-Design-PatternRow-Data-Gateway-Tasarim-Deseni.gif\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2022\/09\/C-Ile-Row-Data-Gateway-Design-PatternRow-Data-Gateway-Tasarim-Deseni.gif\" alt=\"C# \u0130le Row Data Gateway Design Pattern(Row Data Gateway Tasar\u0131m Deseni)\" width=\"351\" height=\"237\" class=\"alignleft size-full wp-image-25563\" \/><\/a>Row Data Gateway i\u00e7erisinde tablodaki s\u00fctunlara kar\u015f\u0131l\u0131k propertyleri ve sql c\u00fcmleciklerini(sorgular\u0131) bar\u0131nd\u0131ran fonksiyonlar\u0131 bar\u0131nd\u0131rmaktad\u0131r. Misal olarak; yandaki diyagrama g\u00f6z atarsan\u0131z e\u011fer &#8216;Person Gateway&#8217; s\u0131n\u0131f\u0131 i\u00e7erisinde hem bir sat\u0131r\u0131na kar\u015f\u0131l\u0131k geldi\u011fi tablodaki s\u00fctunlar\u0131(lastname, firstname, numberOfDependents) hem de bir kay\u0131t eklemek, g\u00fcncellemek vs. gibi i\u015flemler i\u00e7in ise metotlar\u0131(insert, update) bar\u0131nd\u0131rmaktad\u0131r. Ve dikkat ederseniz e\u011fer bir &#8216;Person Gateway&#8217; olu\u015fturabilmek i\u00e7in \u00f6nceki sat\u0131rlarda da bahsedildi\u011fi gibi &#8216;Finder&#8217; s\u0131n\u0131f\u0131ndan istifade etmekteyiz.<\/p>\n<h4>Row Data Gateway Pattern&#8217;\u0131 \u00d6rneklendirelim<\/h4>\n<p>Row Data Gateway pattern bahsi ge\u00e7ti\u011fi \u00fczere olduk\u00e7a basit bir pattern&#8217;d\u0131r. Haliyle \u00f6rneklendirmesi de bir o kadar basit olacakt\u0131r. \u015e\u00f6yle ki;<br \/>\nHer\u015feyden \u00f6nce veritaban\u0131 sorumlulu\u011funu \u00fcstlenecek bir s\u0131n\u0131f in\u015fa ederek ba\u015flayal\u0131m.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npublic static class Database\r\n{\r\n    static SqlConnection _connection;\r\n    static Database()\r\n    {\r\n        object _lock = new();\r\n        lock (_lock)\r\n            _connection = new(&quot;Server=localhost, 1433;Database=RowDataGatewayDB;User Id=sa;Password=1q2w3e4r+!&quot;);\r\n        _connection.Open();\r\n    }\r\n\r\n    public static async Task&lt;int&gt; ExecuteNonQueryAsync(string query, params SqlParameter&#x5B;] parameters)\r\n    {\r\n        SqlCommand command = new(query, _connection);\r\n        command.Parameters.AddRange(parameters);\r\n        return await command.ExecuteNonQueryAsync();\r\n    }\r\n\r\n    public static async Task&lt;SqlDataReader&gt; ExecuteReaderAsync(string query, params SqlParameter&#x5B;] parameters)\r\n    {\r\n        SqlCommand command = new(query, _connection);\r\n        command.Parameters.AddRange(parameters);\r\n        return await command.ExecuteReaderAsync();\r\n    }\r\n}\r\n<\/pre>\n<\/div>\n<p>Ard\u0131ndan &#8216;PersonGateway&#8217; s\u0131n\u0131f\u0131n\u0131 olu\u015ftural\u0131m.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npublic class PersonGateway\r\n{\r\n    public PersonGateway() { }\r\n    public PersonGateway(int id, string name, string surname) { Id = id; Name = name; Surname = surname; }\r\n\r\n    public int Id { get; set; }\r\n    public string Name { get; set; }\r\n    public string Surname { get; set; }\r\n\r\n    public async Task AddPerson()\r\n        =&gt; await AddPerson(Name, Surname);\r\n\r\n    public async Task AddPerson(string name, string surname)\r\n        =&gt; await Database.ExecuteNonQueryAsync(&quot;INSERT Persons(Name, Surname) VALUES(@name, @surname)&quot;\r\n            , new SqlParameter(&quot;name&quot;, name)\r\n            , new SqlParameter(&quot;surname&quot;, surname));\r\n\r\n    public async Task RemoveCustomer()\r\n        =&gt; await RemoveCustomer(Id);\r\n\r\n    public async Task RemoveCustomer(int id)\r\n        =&gt; await Database.ExecuteNonQueryAsync(&quot;DELETE FROM Persons WHERE Id = @id&quot;\r\n            , new SqlParameter(&quot;id&quot;, id));\r\n\r\n    public async Task UpdateCustomer()\r\n        =&gt; await UpdateCustomer(Id, Name, Surname);\r\n\r\n    public async Task UpdateCustomer(int id, string name, string surname)\r\n        =&gt; await Database.ExecuteNonQueryAsync(&quot;UPDATE Persons SET Name = @name, Surname = @surname WHERE Id = @id&quot;\r\n            , new SqlParameter(&quot;id&quot;, id)\r\n            , new SqlParameter(&quot;name&quot;, name)\r\n            , new SqlParameter(&quot;surname&quot;, surname));\r\n}\r\n<\/pre>\n<\/div>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere bu bizim tablodaki bir sat\u0131ra kar\u015f\u0131l\u0131k gelen s\u0131n\u0131f\u0131m\u0131z\u0131n ta kendisidir. Ve i\u00e7erisinde tablodaki kolonlara kar\u015f\u0131l\u0131k gelen property&#8217;ler ve ayr\u0131ca person ekleme, silme ve g\u00fcncelleme ile ilgili sorumluluklar\u0131 \u00fcstlenen metotlar bar\u0131nd\u0131rmaktad\u0131r. Bu s\u0131n\u0131f\u0131n zengin olmas\u0131 operasyonel a\u00e7\u0131dan i\u015fimizi kolayla\u015ft\u0131racakt\u0131r. \u00d6rne\u011fi incelerseniz e\u011fer t\u00fcm metotlar\u0131n parametreli ve parametresiz overload&#8217;lar\u0131n\u0131 g\u00f6rmektesiniz. Parametreli metotlar direkt olarak i\u015flem yapacaklar\u0131 verileri elde ederken, parametresizler ise kendilerinden(kendi instance&#8217;lar\u0131ndaki property&#8217;lerinden) edinmektedir. Bu iki farkl\u0131 tarz\u0131n fark\u0131n\u0131 kullan\u0131mda g\u00f6r\u00fcyor olaca\u011f\u0131z.<\/p>\n<p>\u015eimdi ise sorgulama neticesinde &#8216;Person Gateway&#8217; nesnesini elde etmemizi sa\u011flayacak &#8216;Finder&#8217; s\u0131n\u0131f\u0131n\u0131 olu\u015ftural\u0131m.<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npublic class PersonFinder\r\n{\r\n    public PersonFinder() { }\r\n    readonly PersonGateway _personGateway;\r\n    public PersonFinder(PersonGateway personGateway)\r\n        =&gt; _personGateway = personGateway;\r\n\r\n    public async Task&lt;PersonGateway&gt; GetPersonById()\r\n        =&gt; await GetPersonById(_personGateway.Id);\r\n\r\n    public async Task&lt;PersonGateway&gt; GetPersonById(int id)\r\n    {\r\n        SqlDataReader dataReader = await Database.ExecuteReaderAsync(&quot;SELECT * FROM Persons WHERE Id = @id&quot;\r\n                    , new SqlParameter(&quot;id&quot;, id));\r\n        await dataReader.ReadAsync();\r\n        PersonGateway person = new(int.Parse(dataReader&#x5B;&quot;id&quot;].ToString()), dataReader&#x5B;&quot;name&quot;].ToString(), dataReader&#x5B;&quot;surname&quot;].ToString());\r\n\r\n        await dataReader.CloseAsync();\r\n        await dataReader.DisposeAsync();\r\n        return person;\r\n    }\r\n\r\n    public async Task&lt;List&lt;PersonGateway&gt;&gt; GetPersonByName()\r\n        =&gt; await GetPersonByName(_personGateway.Name);\r\n\r\n    public async Task&lt;List&lt;PersonGateway&gt;&gt; GetPersonByName(string name)\r\n    {\r\n        SqlDataReader dataReader = await Database.ExecuteReaderAsync(&quot;SELECT * FROM Persons WHERE Name = @name&quot;\r\n                  , new SqlParameter(&quot;name&quot;, name));\r\n        List&lt;PersonGateway&gt; persons = new();\r\n        while (await dataReader.ReadAsync())\r\n            persons.Add(new(int.Parse(dataReader&#x5B;&quot;id&quot;].ToString()), dataReader&#x5B;&quot;name&quot;].ToString(), dataReader&#x5B;&quot;surname&quot;].ToString()));\r\n\r\n        await dataReader.CloseAsync();\r\n        await dataReader.DisposeAsync();\r\n        return persons;\r\n    }\r\n\r\n    public async Task&lt;List&lt;PersonGateway&gt;&gt; GetPersonBySurname()\r\n        =&gt; await GetPersonBySurname(_personGateway.Surname);\r\n\r\n    public async Task&lt;List&lt;PersonGateway&gt;&gt; GetPersonBySurname(string surname)\r\n    {\r\n        SqlDataReader dataReader = await Database.ExecuteReaderAsync(&quot;SELECT * FROM Persons WHERE Surname = @surname&quot;\r\n                  , new SqlParameter(&quot;surname&quot;, surname));\r\n        List&lt;PersonGateway&gt; persons = new();\r\n        while (await dataReader.ReadAsync())\r\n            persons.Add(new(int.Parse(dataReader&#x5B;&quot;id&quot;].ToString()), dataReader&#x5B;&quot;name&quot;].ToString(), dataReader&#x5B;&quot;surname&quot;].ToString()));\r\n\r\n        await dataReader.CloseAsync();\r\n        await dataReader.DisposeAsync();\r\n        return persons;\r\n    }\r\n\r\n    public async Task&lt;List&lt;PersonGateway&gt;&gt; GetAllPersons()\r\n    {\r\n        SqlDataReader dataReader = await Database.ExecuteReaderAsync(&quot;SELECT * FROM Persons&quot;);\r\n        List&lt;PersonGateway&gt; persons = new();\r\n        while (await dataReader.ReadAsync())\r\n            persons.Add(new(int.Parse(dataReader&#x5B;&quot;id&quot;].ToString()), dataReader&#x5B;&quot;name&quot;].ToString(), dataReader&#x5B;&quot;surname&quot;].ToString()));\r\n\r\n        await dataReader.CloseAsync();\r\n        await dataReader.DisposeAsync();\r\n        return persons;\r\n    }\r\n}\r\n<\/pre>\n<\/div>\n<p>Bu s\u0131n\u0131f\u0131 da incelerseniz e\u011fer i\u00e7erisinde parametreli ve parametresiz metotlar bar\u0131nd\u0131rmaktad\u0131r. Buradaki ama\u00e7 yine ilgili s\u0131n\u0131f\u0131n i\u015flevselli\u011fini artt\u0131rmak i\u00e7in zenginle\u015ftirmektir. Dikkat ederseniz parametre alan metotlar parametrelerinden gelecek olan de\u011ferlerle beslenirken, almayanlar ise constructor \u00fczerinden edinilmi\u015f de\u011ferler \u00fczerinden sorgulamalar\u0131n\u0131 ger\u00e7ekle\u015ftirecektirler.<\/p>\n<p>\u0130\u015fte bu kadar \ud83d\ude42<\/p>\n<p>\u015eimdi bu tasar\u0131m\u0131 kullanabilmek i\u00e7in;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nPersonGateway eklenecekPerson = new();\r\neklenecekPerson.Name = &quot;Nevin&quot;;\r\neklenecekPerson.Surname = &quot;Y\u0131lmaz&quot;;\r\nawait eklenecekPerson.AddPerson();\r\nawait eklenecekPerson.AddPerson(&quot;Gen\u00e7ay&quot;, &quot;Y\u0131ld\u0131z&quot;);\r\n\r\nPersonGateway guncellenecekPerson = new();\r\nguncellenecekPerson.Id = 101;\r\nguncellenecekPerson.Name = &quot;Nevin&quot;;\r\nguncellenecekPerson.Surname = &quot;Y\u0131ld\u0131z&quot;;\r\nawait guncellenecekPerson.UpdateCustomer();\r\nawait guncellenecekPerson.UpdateCustomer(102, &quot;K\u00fcr\u015fad&quot;, &quot;Y\u0131ld\u0131z&quot;);\r\n\r\nPersonGateway silinecekPerson = new();\r\nsilinecekPerson.Id = 3;\r\nawait silinecekPerson.RemoveCustomer();\r\nawait silinecekPerson.RemoveCustomer(4);\r\n\r\nPersonGateway arananPerson = new() { Id = 10 };\r\nPersonFinder finder = new(arananPerson);\r\nvar person1 = await finder.GetPersonById();\r\nvar person2 = await finder.GetPersonById(10);\r\n<\/pre>\n<\/div>\n<p>\u015feklinde bir \u00e7al\u0131\u015fma yapmam\u0131z yeterli olacakt\u0131r. G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere elimizdeki &#8216;Person Gateway&#8217; nesnesi \u00fczerindeki de\u011ferlerde de i\u015flemler ger\u00e7ekle\u015ftirebildi\u011fimiz gibi direkt parametreler \u00fczerinden gelen de\u011ferlerle de \u00e7al\u0131\u015fabilmekteyiz.<\/p>\n<p>E\u011fer i\u00e7eri\u011fin bu noktas\u0131na kadar geldiyseniz;<br \/>\n<strong><em>La hoca! Sen Row Data Gateway&#8217;in bir kayd\u0131 i\u015fledi\u011fini lakin Table Data Gateway&#8217;in ise t\u00fcm tabloyu i\u015fledi\u011fini s\u00f6ylemi\u015ftin. Halbuki bu iki pattern&#8217;\u0131n birbirine \u00e7ok benzedi\u011fi g\u00f6r\u00fcl\u00fcyor ve \u00f6zellikle her ikisi de tek veya \u00e7ok say\u0131da kay\u0131t d\u00f6nd\u00fcrecek SQL sorgular\u0131n\u0131 kaps\u0131yor! Ne zaman hangisini kullanmam gerekti\u011fini tam olarak anlam\u0131\u015f de\u011filim! Hatta internetten bakt\u0131\u011f\u0131m kadar\u0131yla Martin Fowler day\u0131n\u0131n bile bir kay\u0131t istendi\u011fi zaman Row Data Gateway&#8217;i kullanabilece\u011fimizi s\u00f6ylemesi \u00fczerine bu i\u00e7eri\u011fimizde Row Data Gateway&#8217;de birden fazla kay\u0131t i\u00e7in i\u015flem yapabildi\u011fimizi g\u00f6r\u00fcyoruz. \u00d6yleyse Table Data Gateway \u00e7\u00f6p de\u011fil mi? Ya da sen de bi yanl\u0131\u015f m\u0131 var emmi?<\/em><\/strong> dedi\u011finizi duyar gibiyim \ud83d\ude42<\/p>\n<p>Evet, bu dedi\u011finizde sonuna kadar hakl\u0131s\u0131n\u0131z. Nihayetinde her iki pattern&#8217;\u0131n teorideki farklar\u0131n\u0131 pratikte yans\u0131tmamak kafan\u0131z\u0131n kar\u0131\u015fmas\u0131na sebebiyet verebilir. Bu durumda aradaki fark\u0131 yaratabilmek i\u00e7in \u00f6zellikle odaklan\u0131lmas\u0131 gereken noktalar\u0131 vurgulayal\u0131m istiyorum. Unutmay\u0131n ki; Table Data Gateway SqlDataReader yahut DTO tarz\u0131 nesneler d\u00f6nd\u00fcr\u00fcr. Lakin Row Data Gateway ise sat\u0131r ba\u015f\u0131na bir Gateway s\u0131n\u0131f\u0131 d\u00f6nd\u00fcr\u00fcr.<\/p>\n<p>Bu mant\u0131kla Row Data Gateway&#8217;i a\u015fa\u011f\u0131daki iki yakla\u015f\u0131m e\u015fli\u011finde kullanabilece\u011finizi unutmay\u0131n\u0131z;<\/p>\n<ul>\n<li><strong>Domain Model Object \u0130\u00e7in Veri Sahibi Olarak Row Data Gateway Kullan\u0131m\u0131<\/strong><br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2022\/09\/C-Ile-Row-Data-Gateway-Design-PatternRow-Data-Gateway-Tasarim-Deseni.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2022\/09\/C-Ile-Row-Data-Gateway-Design-PatternRow-Data-Gateway-Tasarim-Deseni.png\" alt=\"C# \u0130le Row Data Gateway Design Pattern(Row Data Gateway Tasar\u0131m Deseni)\" width=\"400\" height=\"417\" class=\"alignleft size-full wp-image-25576\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2022\/09\/C-Ile-Row-Data-Gateway-Design-PatternRow-Data-Gateway-Tasarim-Deseni.png 400w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2022\/09\/C-Ile-Row-Data-Gateway-Design-PatternRow-Data-Gateway-Tasarim-Deseni-288x300.png 288w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/a><br \/>\nDomain model object i\u00e7erisinde Row Data Gateway&#8217;in referans edilerek kullan\u0131lmas\u0131n\u0131 sa\u011flar. Bir nevi domain model object taraf\u0131ndan Row Data Gateway&#8217;in yetkilendirilmesi ve sorumlulu\u011funun \u00fcstlendirilmesidir. Yandaki g\u00f6rsel \u015femaya bakarsan\u0131z e\u011fer &#8216;Student&#8217; nesnesi domain model object \u00f6zelliklerinin hi\u00e7birine sahip olmaks\u0131z\u0131n sadece &#8216;StudentGateway&#8217; s\u0131n\u0131f\u0131n\u0131 referans ederek i\u015flem g\u00f6rmektedir. Bu hem pek tercih edece\u011fimiz bir yakla\u015f\u0131m olmayaca\u011f\u0131 gibi hem de Gateway s\u0131n\u0131f\u0131n\u0131n bulundu\u011fu katman\u0131n &#8216;Domain Layer&#8217; taraf\u0131ndan referans edilmesini sa\u011flayaca\u011f\u0131ndan dolay\u0131 da tavsiye etmeyece\u011fimiz bir y\u00f6ntemdir.<\/p>\n<\/li>\n<li><strong>Domain Model Object&#8217;ten Kurtulmak \u0130\u00e7in Row Data Gateway Kullan\u0131m\u0131<\/strong><br \/>\nBu y\u00f6ntemde ise domain model object&#8217;i komple devre d\u0131\u015f\u0131 b\u0131rakarak, Row Data Gateway nesnelerini do\u011frudan manip\u00fcle etmeyi tercih ediyoruz. B\u00f6ylece bu y\u00f6ntem ile iyi bir \u00f6rneklendirilebilirlik sa\u011flam\u0131\u015f olmasak da hi\u00e7 yoktan ilk yakla\u015f\u0131ma nazaran daha ideal bir davran\u0131\u015f ortaya koymu\u015f oluyoruz.\n<\/li>\n<\/ul>\n<p>\u0130lgilenenlerin faydalanmas\u0131 dile\u011fiyle&#8230;<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/p>\n<p>Not : \u00d6rnek uygulaman\u0131n kaynak kodlar\u0131na a\u015fa\u011f\u0131daki github adresinden eri\u015febilirsiniz.<br \/>\n<a href=\"https:\/\/github.com\/gncyyldz\/Row_Data_Gateway_Design_Pattern\" rel=\"noopener\" target=\"_blank\">https:\/\/github.com\/gncyyldz\/Row_Data_Gateway_Design_Pattern<\/a><\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Bu i\u00e7eri\u011fimizde Veri Katman\u0131 Modelleme Tasar\u0131m Desenleri&#8216;nden olan Row Data Gateway pattern&#8217;\u0131n\u0131 hem teorik hem de pratik olarak inceliyor olaca\u011f\u0131z. Row Data Gateway Design Pattern Nedir? Row Data Gateway, bir veri kayna\u011f\u0131ndaki tek&#46;&#46;&#46;<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":25563,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[153],"tags":[750,4662,4663,4664,4656],"class_list":["post-25557","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-design-pattern","tag-design-pattern","tag-row-data-gateway","tag-row-data-gateway-design-pattern","tag-row-data-gateway-tasarim-deseni","tag-veri-katmani-modelleme"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/25557","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/comments?post=25557"}],"version-history":[{"count":21,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/25557\/revisions"}],"predecessor-version":[{"id":25580,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/25557\/revisions\/25580"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/25563"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=25557"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=25557"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=25557"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}