﻿
{"id":6040,"date":"2017-04-19T22:06:18","date_gmt":"2017-04-19T22:06:18","guid":{"rendered":"http:\/\/www.gencayyildiz.com\/blog\/?p=6040"},"modified":"2017-04-20T14:33:47","modified_gmt":"2017-04-20T14:33:47","slug":"entity-framework-ve-reflection-dayanismasi-ile-model-guncelleme","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/entity-framework-ve-reflection-dayanismasi-ile-model-guncelleme\/","title":{"rendered":"Entity Framework ve Reflection Dayan\u0131\u015fmas\u0131 \u0130le Model G\u00fcncelleme"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Yaz\u0131l\u0131m projelerinde biz yaz\u0131l\u0131mc\u0131lara zamansal, projeyede performans ve h\u0131z olarak her t\u00fcrl\u00fc art\u0131 kazand\u0131ran Entity Framework mimarisi olduk\u00e7a uygun maliyetde bir in\u015fa s\u00fcreci ge\u00e7irmemizi sa\u011flamaktad\u0131r. Tabi bu s\u00fcre\u00e7 yer yer ya\u015fanan aksakl\u0131klar yahut mimarisel prosed\u00fcrlerden kaynaklanan uzun uzun tan\u0131mlar, kompleks ve kullan\u0131\u015fs\u0131z syntaxlar ile yap\u0131lar vs. gibi fakt\u00f6rlerin etkisiyle uzamakta, 1 olan zorluk nedensiz 3&#8217;e \u00e7\u0131kmaktad\u0131r.<\/p>\n<p>Bana sorarsan\u0131z Entity Framework mimarisinde ya\u015fanan bu bahsetti\u011fim handikaplara benzer olan onlarca durumdan bir taneside model g\u00fcncelleme safhas\u0131d\u0131r. Elinizdeki herhangi bir modeli d\u00fczenleyip, veritaban\u0131na fiziksel olarak bu de\u011fi\u015fikli\u011fi yans\u0131tman\u0131n en basit ve sade yolu a\u015fa\u011f\u0131daki gibidir&#8230;(<em>Dikkat : Bundan sonraki \u00f6rneklendirmelerde Northwind veritaban\u0131 ve tablolar\u0131 kullan\u0131lacakt\u0131r.<\/em>)<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            NorthwindEntities VeriTabani = new NorthwindEntities();\r\n            Personeller Personel = VeriTabani.Personeller.FirstOrDefault(p =&gt; p.PersonelID == 3);\r\n            Personel.Adi = &quot;Gen\u00e7ay&quot;;\r\n            Personel.SoyAdi = &quot;Y\u0131ld\u0131z&quot;;\r\n            VeriTabani.SaveChanges();\r\n        }\r\n    }\r\n<\/pre>\n<p>Tabi ki de bu \u015fekilde kullan\u0131m yerine daha sistematik \u00e7al\u0131\u015f\u0131p farkl\u0131 s\u0131n\u0131flarda bu i\u015flemi fonksiyonel hale getirebilir, Base Class&#8217;lar \u00fczerinde Update i\u015flevselli\u011finde metotlar olu\u015fturabilir ya da daha farkl\u0131 fikirlerle hareket edebiliriz. Ben bu son dedi\u011fimi, yani farkl\u0131 bir fikir ile bu i\u015flemi ger\u00e7ekle\u015ftirmeyi g\u00f6sterece\u011fim.<\/p>\n<p><a href=\"http:\/\/www.gencayyildiz.com\/blog\/cta-system-reflection-kutuphanesi\/\" target=\"_blank\">Reflection<\/a>  k\u00fct\u00fcphanesinin nimetlerinden faydalanarak Entity Framework \u00fczerinde bir \u00e7al\u0131\u015fma ger\u00e7ekle\u015ftirece\u011fiz. Olu\u015fturaca\u011f\u0131m yap\u0131 birazdan da g\u00f6rece\u011finiz \u00fczere Generic Extension metot olarak tasarlanacak ve bu y\u00fczden her model \u00fczerinden direkt olarak eri\u015filebilir olacakt\u0131r.<\/p>\n<p>Hadi buyrun yap\u0131m\u0131z\u0131 in\u015fa edelim.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    static class Extension\r\n    {\r\n        public static T ModelGuncelle&lt;T&gt;(this T EskiModel, T YeniModel, NorthwindEntities VeriTabani) where T : class, new()\r\n        {\r\n            EskiModel.GetType().GetProperties().ToList().ForEach(em =&gt; YeniModel.GetType().GetProperties().ToList().ForEach(ym =&gt;\r\n            {\r\n                if (!em.Name.ToUpper().Contains(&quot;ID&quot;) || !ym.Name.ToUpper().Contains(&quot;ID&quot;))\r\n                    if (ym.Name == em.Name)\r\n                        em.SetValue(EskiModel, ym.GetValue(YeniModel));\r\n            }));\r\n\r\n            VeriTabani.SaveChanges();\r\n\r\n            return EskiModel;\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funda g\u00f6rm\u00fc\u015f oldu\u011funuz gibi &#8220;ModelGuncelle&#8221; Extension metodunu Generic bir \u015fekilde olu\u015fturmu\u015f olduk. Metodun i\u00e7eri\u011fine bakarsak e\u011fer, kullan\u0131ld\u0131\u011f\u0131 modelin reflection ile propertylerine eri\u015fmekte ve parametreden gelen g\u00fcncel modeldeki bilgileri tek tek ilgili modelin nesnesine set etmekte ve parametreden gelen o an kullanmakta oldu\u011fumuz veritaban\u0131 nesnesinin &#8220;SaveChanges&#8221; metodunu tetiklemektedir. Tabi bu i\u015flemi yaparken &#8220;\u0131d&#8221; kolonlar\u0131n\u0131n \u00f6nlemi al\u0131nmakta ve gerekli algoritmik \u00e7al\u0131\u015fmalar yap\u0131lmaktad\u0131r.<\/p>\n<p>\u015eimdide &#8220;ModelGuncelle&#8221; metodunun kullan\u0131m\u0131n\u0131 ele alal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            NorthwindEntities VeriTabani = new NorthwindEntities();\r\n            Personeller Personel = VeriTabani.Personeller.FirstOrDefault(p =&gt; p.PersonelID == 29);\r\n            Personeller GuncelPersonel = new Personeller { Adi = &quot;Gen\u00e7ay&quot;, SoyAdi = &quot;Y\u0131ld\u0131z&quot;, Unvan = &quot;Yaz\u0131l\u0131m ve Veritaban\u0131 Uzman\u0131&quot; };\r\n            Personel.ModelGuncelle(GuncelPersonel, VeriTabani);\r\n        }\r\n    }\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere yapm\u0131\u015f oldu\u011fumuz \u00e7al\u0131\u015fma yukar\u0131daki gibi kolay ve pratik bir g\u00fcncelleme i\u015flevi sunmaktad\u0131r.<\/p>\n<p>Bunun d\u0131\u015f\u0131nda yap\u0131m\u0131z\u0131 dahada geli\u015ftirmemiz gerekebilir. \u00d6rne\u011fin a\u015fa\u011f\u0131daki durumu ele alal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            NorthwindEntities VeriTabani = new NorthwindEntities();\r\n            Personeller Personel = VeriTabani.Personeller.FirstOrDefault(p =&gt; p.PersonelID == 29);\r\n            Personeller GuncelPersonel = new Personeller { Adi = &quot;Gen\u00e7ay&quot;, SoyAdi = null, Unvan = &quot;Yaz\u0131l\u0131m ve Veritaban\u0131 Uzman\u0131&quot; };\r\n            Personel.ModelGuncelle(GuncelPersonel, VeriTabani);\r\n        }\r\n    }\r\n<\/pre>\n<p>Dikkat ederseniz SoyAdi kolonu &#8220;null&#8221; de\u011fer almaktad\u0131r. Bu \u015fekilde projemizi derleyip \u00e7al\u0131\u015ft\u0131rd\u0131\u011f\u0131m\u0131z zaman hata alaca\u011f\u0131z. \u00c7\u00fcnk\u00fc Northwind veritaban\u0131n\u0131n Personeller tablosunda SoyAdi kolonu null olamaz. Bunun d\u0131\u015f\u0131nda null olarak ayarlad\u0131\u011f\u0131n\u0131z propertylerin asl\u0131nda veritaban\u0131nda bulundu\u011fu \u015fekilde kalmas\u0131n\u0131da isteyebilirsiniz. O halde a\u015fa\u011f\u0131daki gibi bir if kontrol\u00fc i\u015finizi fazlas\u0131yla g\u00f6recektir&#8230;<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    static class Extension\r\n    {\r\n        public static T ModelGuncelle&lt;T&gt;(this T EskiModel, T YeniModel, NorthwindEntities VeriTabani) where T : class, new()\r\n        {\r\n            EskiModel.GetType().GetProperties().ToList().ForEach(em =&gt; YeniModel.GetType().GetProperties().ToList().ForEach(ym =&gt;\r\n            {\r\n                if (!em.Name.ToUpper().Contains(&quot;ID&quot;) || !ym.Name.ToUpper().Contains(&quot;ID&quot;))\r\n                    if (ym.GetValue(YeniModel) != null)\r\n                        if (ym.Name == em.Name)\r\n                            em.SetValue(EskiModel, ym.GetValue(YeniModel));\r\n            }));\r\n\r\n            VeriTabani.SaveChanges();\r\n\r\n            return EskiModel;\r\n        }\r\n    }\r\n<\/pre>\n<p>\u0130\u015fte bu \u015fekilde bir kontrolden sonra bir \u00f6nceki vermi\u015f oldu\u011fumuz null kullan\u0131m \u00f6rne\u011finden beklenen hata al\u0131nmayacakt\u0131r.<\/p>\n<p>\u015eimdi bir durumu daha konu\u015fmak istiyorum ki o da modelimize eklenen harici propertylerdir. Kastetti\u011fim herhangi bir modele partial olu\u015fturarak bu modele ek propertylerde kazand\u0131rm\u0131\u015f olabilirsiniz. Kazand\u0131r\u0131lan bu property read only ya da write only olabilir. Bu tarz durumlarda olu\u015fturmu\u015f oldu\u011fumuz &#8220;ModelGuncelle&#8221; metodu i\u015flevselli\u011fini yitirecek ve hata verecektir. \u00c7\u00fcnk\u00fc birazdan inceleyece\u011fimiz \u00fczere \u015fuan yapm\u0131\u015f oldu\u011fumuz mevcut reflection \u00e7al\u0131\u015fmas\u0131 ile kullan\u0131lan modellerin t\u00fcm propertyleri \u00fczerinde gerekli \u015fartlar do\u011frultusunda set ve get i\u015flemleri ger\u00e7ekle\u015ftirilmektedir. Ee haliyle d\u00fc\u015f\u00fcn\u00fcrseniz sadece get blo\u011fu olan bir propertynin set blo\u011funun tetiklenmek istenmesi \u015fuandaki algoritma in\u015fam\u0131za g\u00f6re olas\u0131d\u0131r.<\/p>\n<p>\u00d6ncelikle gelin olas\u0131 hatay\u0131 verecek durumu \u00f6rneklendirecek bir yap\u0131 olu\u015ftural\u0131m. Ard\u0131ndan \u00e7\u00f6z\u00fcm\u00fcn\u00fc konu\u015fal\u0131m.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    partial class Personeller\r\n    {\r\n        public int PersonelSatisSayisi { get; } = 0;\r\n        public List&lt;Satislar&gt; PersonelinEnGozdeSatislari\r\n        {\r\n            set\r\n            {\r\n                 ...\r\n            }\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer Personeller entitysine bir partial olu\u015fturulmu\u015f ve bu partial \u00fczerinden Personeller s\u0131n\u0131f\u0131na iki adet property eklenmi\u015ftir. Bu propertylerden biri get(read only) bir di\u011feride set(write only) olarak tasarlanm\u0131\u015ft\u0131r.<\/p>\n<p>E\u011fer ki biz metodumuzu Personeller modeli \u00fczerinde derleyip \u00e7al\u0131\u015ft\u0131r\u0131rsak yukar\u0131daki sat\u0131rlarda da bahsetti\u011fim gibi reflection i\u015flemlerinde ilgili propertyler \u00fczerinde set ve get i\u015flemleri yap\u0131lmaya \u00e7al\u0131\u015f\u0131lacakt\u0131r ve art\u0131k yap\u0131s\u0131na g\u00f6re her iki propertyden de exception al\u0131nacakt\u0131r.<\/p>\n<p>\u0130\u015fte bu olas\u0131 durumu kontrol alt\u0131na alabilmek i\u00e7in ben Attribute y\u00f6ntemi tasarlam\u0131\u015f bulunmaktay\u0131m. Tasarlad\u0131\u011f\u0131m bir attribute ile modeller i\u00e7erisindeki propertyleri i\u015faretlemekte ve reflection i\u015flemleri s\u0131ras\u0131nda da o anki property ilgili attribute ile i\u015faretli ise i\u015flemlere tabi tutulmamaktad\u0131r. <\/p>\n<p>\u00d6ncelikle attributeu olu\u015ftural\u0131m ve ard\u0131ndan yukar\u0131da ekledi\u011fimiz propertyleri bu attribute ile i\u015faretleyelim.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    partial class Personeller\r\n    {\r\n        &#x5B;Model(false)]\r\n        public int PersonelSatisSayisi { get; } = 0;\r\n        &#x5B;Model(false)]\r\n        public List&lt;Satislar&gt; PersonelinEnGozdeSatislari\r\n        {\r\n            set\r\n            {\r\n\r\n            }\r\n        }\r\n    }\r\n\r\n    class ModelAttribute : Attribute\r\n    {\r\n        public bool Durum { get; set; }\r\n        public ModelAttribute() { }\r\n        public ModelAttribute(bool Durum) =&gt; this.Durum = Durum;\r\n    }\r\n<\/pre>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere Model isminde bir attribute olu\u015fturdum. \u0130smi ve i\u00e7eri\u011fi \u00e7ok \u00f6nemli de\u011fil. Ben burada \u00f6rnek olmas\u0131 a\u00e7\u0131s\u0131ndan i\u00e7erisine model attributeu ile i\u015faretlenen propertynin durumunuda belirterek &#8220;bu property modeldir ya da de\u011fildir&#8221;i daha net diyebilmek i\u00e7in Durum bilgisi ekledim.<\/p>\n<p>\u015eimdi s\u0131ra &#8220;ModelGuncelle&#8221; isimli Extension metodumuzu g\u00fcncellemeye geldi.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    static class Extension\r\n    {\r\n        public static T ModelGuncelle&lt;T&gt;(this T EskiModel, T YeniModel, NorthwindEntities VeriTabani) where T : class, new()\r\n        {\r\n            EskiModel.GetType().GetProperties().ToList().ForEach(em =&gt; YeniModel.GetType().GetProperties().ToList().ForEach(ym =&gt;\r\n            {\r\n                if (!em.Name.ToUpper().Contains(&quot;ID&quot;) || !ym.Name.ToUpper().Contains(&quot;ID&quot;))\r\n                    if (ym.Name == em.Name)\r\n                    {\r\n                        bool GetSetDurum = true;\r\n                        var propertyattributes = em.GetCustomAttributes(true).ToList();\r\n                        if (propertyattributes.Any() &amp;&amp; propertyattributes != null)\r\n                            propertyattributes.ForEach(attr =&gt;\r\n                            {\r\n                                if (attr is ModelAttribute mattr)\r\n                                    if (mattr.Durum == false)\r\n                                        GetSetDurum = !GetSetDurum;\r\n                            });\r\n\r\n                        if (GetSetDurum)\r\n                            if (ym.GetValue(YeniModel) != null)\r\n                                em.SetValue(EskiModel, ym.GetValue(YeniModel));\r\n                    }\r\n            }));\r\n\r\n            VeriTabani.SaveChanges();\r\n\r\n            return EskiModel;\r\n        }\r\n    }\r\n<\/pre>\n<p>Yukar\u0131daki kod blo\u011funu incelerseniz e\u011fer reflection ile propertylerini tarad\u0131\u011f\u0131m\u0131z modeldeki ilgili propertynin attributelar\u0131n\u0131 elde ederek ModelAttribute olup olmad\u0131\u011f\u0131na bak\u0131yoruz, e\u011fer Model attribute ise Durum propertysini kontrol edip false ise ilgili property \u00fczerinde i\u015flem yapm\u0131yoruz.<\/p>\n<p>\u0130\u015fte bu \u015fekilde de g\u00fczel, temiz ve bir o kadar da korunakl\u0131 Entity Framework ve Reflection ikilisiyle modellerimizi fiziksel olarak g\u00fcncellemi\u015f oluyoruz.<\/p>\n<p>Ayriyetten; g\u00fcncelleme durumlar\u0131nda illa bir harici modele ba\u011fl\u0131 kalmamak, sadece tek bir propertynin de\u011ferini g\u00fcncellemek i\u00e7in &#8220;ModelGuncelle&#8221; metodunun a\u015fa\u011f\u0131daki gibi bir overload\u0131n\u0131 olu\u015fturabiliriz.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        public static T ModelGuncelle&lt;T&gt;(this T EskiModel, string PropertyAdi, object Deger, NorthwindEntities VeriTabani) where T : class, new()\r\n        {\r\n            EskiModel.GetType().GetProperties().ToList().ForEach(em =&gt;\r\n            {\r\n                if (!em.Name.ToUpper().Contains(&quot;ID&quot;))\r\n                    if (PropertyAdi == em.Name)\r\n                    {\r\n                        bool GetSetDurum = true;\r\n                        var propertyattributes = em.GetCustomAttributes(true).ToList();\r\n                        if (propertyattributes.Any() &amp;&amp; propertyattributes != null)\r\n                            propertyattributes.ForEach(attr =&gt;\r\n                            {\r\n                                if (attr is ModelAttribute mattr)\r\n                                    if (mattr.Durum == false)\r\n                                        GetSetDurum = !GetSetDurum;\r\n                            });\r\n\r\n                        if (GetSetDurum)\r\n                            if (Deger != null)\r\n                                em.SetValue(EskiModel, Deger);\r\n                    }\r\n            });\r\n\r\n            VeriTabani.SaveChanges();\r\n\r\n            return EskiModel;\r\n        }\r\n<\/pre>\n<p>Bu overload\u0131n da kullan\u0131l\u0131\u015f\u0131 a\u015fa\u011f\u0131daki gibi olacakt\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Program\r\n    {\r\n        static void Main(string&#x5B;] args)\r\n        {\r\n            NorthwindEntities VeriTabani = new NorthwindEntities();\r\n            Personeller Personel = VeriTabani.Personeller.FirstOrDefault(p =&gt; p.PersonelID == 29);\r\n            Personeller GuncelPersonel = new Personeller() { Adi = &quot;Mehmet&quot;, SoyAdi = &quot;Ahmet&quot; };\r\n            Personel.ModelGuncelle(&quot;Adi&quot;, &quot;Hilmi&quot;, VeriTabani);\r\n\r\n            \/\/Veya\r\n\r\n            Satislar Satis = VeriTabani.Satislar.First();\r\n            Satis.ModelGuncelle(&quot;SatisTarihi&quot;, DateTime.Now, VeriTabani);\r\n        }\r\n    }\r\n<\/pre>\n<p>Evet sevgili okurlar\u0131m&#8230;<br \/>\nA\u011f\u0131r bir yaz\u0131 oldu\u011funun fark\u0131nday\u0131m. Ama t\u00fcm detaylar\u0131 aktarabilmek i\u00e7in bu \u015fekilde makaleyi \u015fi\u015firmem gerekti\u011fine umar\u0131m sizlerde kanaat getirmi\u015fsinizdir. Makale s\u00fcrecinde i\u00e7erikleriyle bize e\u015flik eden ve nihayetinde tam in\u015fa edilen ilgili Extension metodunu a\u015fa\u011f\u0131da a\u00e7\u0131k kaynak olarak sizlere sunuyorum.<\/p>\n<p><a href=\"http:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2017\/04\/Entity-Framework-Reflection-Extension-Metot.rar\" target=\"_blank\">Entity Framework &#8211; Reflection Extension Method dosyas\u0131n\u0131 indirmek i\u00e7in t\u0131klay\u0131n\u0131z.<\/a><\/p>\n<p>Okudu\u011funuz i\u00e7in te\u015fekk\u00fcr ederim.<br \/>\nSonraki yaz\u0131lar\u0131mda g\u00f6r\u00fc\u015fmek \u00fczere&#8230;<br \/>\n\u0130yi \u00e7al\u0131\u015fmalar&#8230;<\/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, Yaz\u0131l\u0131m projelerinde biz yaz\u0131l\u0131mc\u0131lara zamansal, projeyede performans ve h\u0131z olarak her t\u00fcrl\u00fc art\u0131 kazand\u0131ran Entity Framework mimarisi olduk\u00e7a uygun maliyetde bir in\u015fa s\u00fcreci ge\u00e7irmemizi sa\u011flamaktad\u0131r. Tabi bu s\u00fcre\u00e7 yer yer ya\u015fanan aksakl\u0131klar yahut&#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":3739,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,955],"tags":[963,1739,1408,1740],"class_list":["post-6040","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-sharp-c","category-entity-framework","tag-entity-framework","tag-entity-framework-ve-reflection","tag-reflection","tag-reflection-ile-entity-framework"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/6040","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=6040"}],"version-history":[{"count":0,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/6040\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/3739"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=6040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=6040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=6040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}