﻿
{"id":19936,"date":"2020-12-14T17:05:43","date_gmt":"2020-12-14T17:05:43","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=19936"},"modified":"2020-12-14T17:06:08","modified_gmt":"2020-12-14T17:06:08","slug":"entity-framework-core-owned-entities-and-table-splitting","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/entity-framework-core-owned-entities-and-table-splitting\/","title":{"rendered":"Entity Framework Core &#8211; Owned Entities and Table Splitting"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Entity Framework Core tasar\u0131mlar\u0131nda bir entity&#8217;nin olmas\u0131 gereken in\u015fa kurallar\u0131n\u0131n d\u0131\u015f\u0131na \u00e7\u0131karak par\u00e7alamak ve grupsal olarak property&#8217;lerini farkl\u0131 class&#8217;lar da tutmak isteyebiliriz. Bu class&#8217;lar, yap\u0131sal olarak entity type&#8217;a benzeyebilirler lakin davran\u0131\u015fsal olarak, ana entity&#8217;nin farkl\u0131 property&#8217;lerini temsil etmektedirler.<\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-19937\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-1024x374.png\" alt=\"Entity Framework Core - Owned Entities and Table Splitting\" width=\"1024\" height=\"374\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-1024x374.png 1024w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-300x110.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-768x281.png 768w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting.png 1377w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><br \/>\nYukar\u0131daki g\u00f6rseli incelerseniz e\u011fer, &#8216;Employee&#8217; entity&#8217;sinin &#8216;Name&#8217;, &#8216;MiddleName&#8217; ve &#8216;LastName&#8217; bilgileri bir grup olarak &#8216;EmployeeName&#8217; s\u0131n\u0131f\u0131na, benzer mant\u0131kla &#8216;StreetAdress&#8217; ve &#8216;Location&#8217; bilgileri ise &#8216;Address&#8217; s\u0131n\u0131f\u0131na al\u0131nm\u0131\u015ft\u0131r. Bu grupsal property&#8217;leri bar\u0131nd\u0131ran entity type misali s\u0131n\u0131flar nihai olarak ana entity&#8217;de navigation property olarak tarif edilmektedirler.<\/p>\n<p>Normal EF Core kurallar\u0131nda t\u00fcm entity&#8217;lerin bir primary key property&#8217;si olmal\u0131d\u0131r. Haliyle EF Core navigation property&#8217;ler ile kurulan relation durumlar\u0131nda ili\u015fkisel olarak bu property \u00fczerinden foreign key&#8217;leri sa\u011flayaca\u011f\u0131n\u0131 bilmektedirler. Halbuki buradaki ama\u00e7 ne ili\u015fkisel bir tasar\u0131m yapmak ne de primary key&#8217;i olmayan bir tablo olu\u015fturmak. Buradaki ama\u00e7 &#8216;Employee&#8217; t\u00fcr\u00fcn\u00fcn property&#8217;lerini grupsal olarak farkl\u0131 s\u0131n\u0131flara da\u011f\u0131tmak ve o \u015fekilde y\u00f6netmektir. \u0130\u015fte b\u00f6yle veritaban\u0131 a\u00e7\u0131s\u0131ndan normalizasyona ayk\u0131r\u0131 tasar\u0131mlar\u0131n s\u00f6z konusu oldu\u011fu durumlarda Owned Entities \u00f6zelli\u011fi ile tasar\u0131m\u0131 ORM arac\u0131na izah edebilmekte ve bunlar\u0131n bir entity de\u011fil, var olan entity&#8217;nin alt par\u00e7alar\u0131 oldu\u011funu s\u00f6yleyebilmekteyiz.<\/p>\n<p>Bunun i\u00e7in context nesnesinin direkt &#8216;OnModelCreating&#8217; metodunu kullanabilece\u011fimiz gibi ayriyeten &#8216;IEntityTypeConfiguration&lt;T&gt;&#8217; t\u00fcr\u00fcnden bir konfig\u00fcrasyon yap\u0131lanmas\u0131n\u0131 da kullanabiliriz.<\/p>\n<p>\u0130lk olarak &#8216;OnModelCreating&#8217; metodunda ilgili konfig\u00fcrasyonu ele al\u0131rsak e\u011fer :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        protected override void OnModelCreating(ModelBuilder modelBuilder)\r\n        {\r\n            modelBuilder.Entity&lt;Employee&gt;().OwnsOne(e =&gt; e.Address);\r\n            modelBuilder.Entity&lt;Employee&gt;().OwnsOne(e =&gt; e.EmployeeName);\r\n            base.OnModelCreating(modelBuilder);\r\n        }\r\n<\/pre>\n<p>g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere ilgili &#8216;OwnsOne&#8217; fonksiyonu sayesinde &#8216;Employee&#8217; s\u0131n\u0131f\u0131n alt\u0131ndaki &#8216;Address&#8217; ve &#8216;EmployeeName&#8217; navigation property&#8217;lerinin ili\u015fkisel bir tablo de\u011fil, esas\u0131nda alt property tan\u0131mlamalar\u0131n\u0131 tutan gruplar oldu\u011funu ifade etmi\u015f bulunmaktay\u0131z.<\/p>\n<p>Benzer i\u015fi &#8216;IEntityTypeConfiguration&lt;T&gt;&#8217; interface&#8217;i ile ger\u00e7ekle\u015ftirirsek e\u011fer :<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class EmployeeConfiguration : IEntityTypeConfiguration&lt;Employee&gt;\r\n    {\r\n        public void Configure(EntityTypeBuilder&lt;Employee&gt; builder)\r\n        {\r\n            builder.OwnsOne(e =&gt; e.Address);\r\n            builder.OwnsOne(e =&gt; e.EmployeeName);\r\n        }\r\n    }\r\n<\/pre>\n<p>\u0130lgili interface&#8217;den t\u00fcreyen &#8216;EmployeeConfiguration&#8217; s\u0131n\u0131f\u0131 \u00fczerinde implement edilen &#8216;Configure&#8217; metodunda yine &#8216;OwnsOne&#8217; fonksiyonuyla ilgili property gruplar\u0131 belirtilmektedir. Bu tasar\u0131mdan sonra ilgili konfig\u00fcrasyon dosyas\u0131, context s\u0131nf\u0131ndaki &#8216;OnModelCreating&#8217; fonksiyonunda a\u015fa\u011f\u0131daki gibi &#8216;ApplyConfiguration&#8217; metodu ile ilgili ORM&#8217;ye dahil edilmesi gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n        protected override void OnModelCreating(ModelBuilder modelBuilder)\r\n        {\r\n            modelBuilder.ApplyConfiguration(new EmployeeConfiguration());\r\n            base.OnModelCreating(modelBuilder);\r\n        }\r\n<\/pre>\n<p>Normalde bu konfig\u00fcrasyonlar\u0131 yapmasak EF Core &#8216;Employee&#8217; alt\u0131ndaki &#8216;EmployeeName&#8217; ve &#8216;Address&#8217; property&#8217;lerini bir ili\u015fkisel navigation property olarak alg\u0131layacak ve migration olu\u015fturma s\u00fcrecinde primary key kolonlar\u0131 tan\u0131mlanmad\u0131\u011f\u0131 i\u00e7in a\u015fa\u011f\u0131daki hatay\u0131 verecektir.<br \/>\n<a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-1.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-1.png\" alt=\"\" width=\"833\" height=\"58\" class=\"aligncenter size-full wp-image-19944\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-1.png 833w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-1-300x21.png 300w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-1-768x53.png 768w\" sizes=\"auto, (max-width: 833px) 100vw, 833px\" \/><\/a><\/p>\n<p>Amma velakin &#8216;OwnsOne&#8217; metodu sayesinde ilgili property&#8217;lerin ili\u015fkisel navigation property olmad\u0131\u011f\u0131n\u0131, ilgili entity&#8217;nin property&#8217;lerini bar\u0131nd\u0131ran alt class&#8217;lar oldu\u011funu bildirmi\u015f olmaktay\u0131z. Dolay\u0131s\u0131yla migration basarken bir problemle kar\u015f\u0131la\u015f\u0131lmayacak ve migrate neticesinde ilgili tabloyu a\u015fa\u011f\u0131daki gibi generate edecektir.<\/p>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-2.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-2.png\" alt=\"Entity Framework Core - Owned Entities and Table Splitting\" width=\"361\" height=\"169\" class=\"alignleft size-full wp-image-19945\" srcset=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-2.png 361w, https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-2-300x140.png 300w\" sizes=\"auto, (max-width: 361px) 100vw, 361px\" \/><\/a>Yandaki g\u00f6rselde g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere &#8216;Employees&#8217; entity&#8217;si i\u00e7erisinde navigation property olarak bildirilen alt property gruplar\u0131 yap\u0131sal olarak &#8216;Employees&#8217; tablosunda kolon olarak generate edilmi\u015flerdir. Kolon isimlerine dikkat ederseniz hangi class&#8217;tan geliyorsa onu bildirecek \u015fekilde nitelendirilmi\u015ftir. E\u011fer ki olu\u015fturulacak kolonlar\u0131n ismini de\u011fi\u015ftirmek istiyorsan\u0131z ilgili property&#8217;lere a\u015fa\u011f\u0131daki gibi m\u00fcdahalede bulunman\u0131z gerekmektedir.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n            builder.OwnsOne(e =&gt; e.Address).Property(p =&gt; p.Location).HasColumnName(&quot;Location&quot;);\r\n            builder.OwnsOne(e =&gt; e.Address).Property(p =&gt; p.StreetAddress).HasColumnName(&quot;StreetAddress&quot;);\r\n            builder.OwnsOne(e =&gt; e.EmployeeName).Property(e =&gt; e.LastName).HasColumnName(&quot;LastName&quot;);\r\n            builder.OwnsOne(e =&gt; e.EmployeeName).Property(e =&gt; e.MiddleName).HasColumnName(&quot;MiddleName&quot;);\r\n            builder.OwnsOne(e =&gt; e.EmployeeName).Property(e =&gt; e.Name).HasColumnName(&quot;Name&quot;);\r\n<\/pre>\n<p><a href=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.gencayyildiz.com\/blog\/wp-content\/uploads\/2020\/12\/Entity-Framework-Core-Owned-Entities-and-Table-Splitting-3.png\" alt=\"Entity Framework Core - Owned Entities and Table Splitting\" width=\"272\" height=\"169\" class=\"alignright size-full wp-image-19946\" \/><\/a>Haliyle bu \u015fekilde yap\u0131lan bir \u00e7al\u0131\u015fma neticesinde kolon isimleri istedi\u011finiz gibi edinilebilmektedir. G\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere Table Splitting operasyonu neticesinde veritaban\u0131ndaki herhangi bir tablonun kar\u015f\u0131l\u0131\u011f\u0131 olan bir entity&#8217;i yaz\u0131l\u0131m k\u0131sm\u0131nda b\u00f6lebilmekte ve bir b\u00fct\u00fcn olarak kullanmaya devam edebilmekteyiz.<\/p>\n<p><strong>Owned Attribute&#8217;u<\/strong><br \/>\nEntity b\u00f6lme i\u015flemini ger\u00e7ekle\u015ftirebilmek i\u00e7in yukar\u0131da ele al\u0131nan y\u00f6ntem d\u0131\u015f\u0131nda ayriyeten &#8216;Owned&#8217; attribute&#8217;unu kullanabilirsiniz. Bu attribute ile ana entity taraf\u0131ndan navigation property olarak referans edilen t\u00fcm par\u00e7alar\u0131 i\u015faretlemeniz ili\u015fkisel bir tablo tasar\u0131m\u0131 olmad\u0131\u011f\u0131na dair bilgilendirme yapman\u0131z i\u00e7in yeterli olacakt\u0131r.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    class Employee\r\n    {\r\n        public int Id { get; set; }\r\n        public bool IsActive { get; set; }\r\n        public EmployeeName EmployeeName { get; set; }\r\n        public Address Address { get; set; }\r\n    }\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;Owned()]\r\n    class EmployeeName\r\n    {\r\n        public string Name { get; set; }\r\n        public string MiddleName { get; set; }\r\n        public string LastName { get; set; }\r\n    }\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    &#x5B;Owned()]\r\n    class Address\r\n    {\r\n        public string StreetAddress { get; set; }\r\n        public string Location { get; set; }\r\n    }\r\n<\/pre>\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<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>Merhaba, Entity Framework Core tasar\u0131mlar\u0131nda bir entity&#8217;nin olmas\u0131 gereken in\u015fa kurallar\u0131n\u0131n d\u0131\u015f\u0131na \u00e7\u0131karak par\u00e7alamak ve grupsal olarak property&#8217;lerini farkl\u0131 class&#8217;lar da tutmak isteyebiliriz. Bu class&#8217;lar, yap\u0131sal olarak entity type&#8217;a benzeyebilirler lakin davran\u0131\u015fsal olarak, ana&#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":19937,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2914],"tags":[2850,4014,4015,4010,4012,4011,4013],"class_list":["post-19936","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-entity-framework-core","tag-entity-framework-core","tag-entity-framework-core-owned-entities","tag-entity-framework-core-table-splitting","tag-ientitytypeconfiguration","tag-owned-entities","tag-owned-entities-and-table-splitting","tag-table-splitting"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/19936","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=19936"}],"version-history":[{"count":11,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/19936\/revisions"}],"predecessor-version":[{"id":19951,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/19936\/revisions\/19951"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/19937"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=19936"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=19936"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=19936"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}