﻿
{"id":27126,"date":"2024-08-18T12:10:09","date_gmt":"2024-08-18T12:10:09","guid":{"rendered":"https:\/\/www.gencayyildiz.com\/blog\/?p=27126"},"modified":"2024-08-18T12:10:09","modified_gmt":"2024-08-18T12:10:09","slug":"ef-core-8-complex-types","status":"publish","type":"post","link":"https:\/\/www.gencayyildiz.com\/blog\/ef-core-8-complex-types\/","title":{"rendered":"EF Core 8 &#8211; Complex Types"},"content":{"rendered":"<div id=\"fb-root\"><\/div>\n<p>Merhaba,<\/p>\n<p>Bu i\u00e7eri\u011fimizde EF Core&#8217;da ki <a href=\"https:\/\/www.gencayyildiz.com\/blog\/entity-framework-core-owned-entities-and-table-splitting\/\" rel=\"noopener\" target=\"_blank\">Owned Types<\/a> \u00f6zelli\u011fine olduk\u00e7a benzerlik g\u00f6steren ve biz geli\u015ftiriciler a\u00e7\u0131s\u0131ndan bir entity i\u00e7erisindeki property&#8217;lerin d\u00fczenlenmesine olanak tan\u0131yan Complex Types \u00f6zelli\u011fini inceliyor olaca\u011f\u0131z. <\/p>\n<p>\u00d6ncelikle Owned Types \u00f6zelli\u011fini hat\u0131rlayarak ba\u015flayal\u0131m&#8230; Owned Types, bir entity&#8217;nin par\u00e7as\u0131 olarak sahip oldu\u011fu t\u00fcrleri ifade etmektedir. Bu t\u00fcrler kendi ba\u015flar\u0131na bir tabloya sahip de\u011fildirler. Sadece sahip olduklar\u0131 entity ile birlikte veritaban\u0131 seviyesinde ayn\u0131 tabloda yer almaktad\u0131rlar. Bunu daha iyi anlayabilmek i\u00e7in yukar\u0131da giri\u015f paragraf\u0131nda referans etti\u011fim i\u00e7eri\u011fe g\u00f6z atman\u0131zda fayda g\u00f6rmekteyim.<\/p>\n<p>Complex Types ise yine bir entity&#8217;nin par\u00e7as\u0131 olarak sahip oldu\u011fu t\u00fcrleri ifade etmektedir lakin Owned Types&#8217;dan farkl\u0131 olarak baz\u0131 yeteneklere sahiptir. Bu yeteneklerden en \u00f6nemlisi bir alt t\u00fcrden \u00fcretilmi\u015f instance&#8217;\u0131n ayn\u0131 anda farkl\u0131 entity&#8217;ler taraf\u0131ndan kullan\u0131labilmesidir. \u00c7\u00fcnk\u00fc bu davran\u0131\u015f Owned Type&#8217;lar da ge\u00e7ersizdir.<\/p>\n<p>Bunu en iyi \u015f\u00f6yle bir \u00f6rnek \u00fczerinden izah edebiliriz;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npublic struct Address\r\n{\r\n    public string Street { get; set; }\r\n    public string City { get; set; }\r\n    public string State { get; set; }\r\n    public string Country { get; set; }\r\n    public string PostalCode { get; set; }\r\n}\r\n<\/pre>\n<\/div>\n<p>Diyelim ki elimizde <em>Address<\/em> ad\u0131nda yukar\u0131daki gibi bir nesnemiz olsun ve bu nesneyi a\u015fa\u011f\u0131daki gibi <em>Order<\/em> ve &#8216;Customer&#8217; entity&#8217;lerinde kulland\u0131\u011f\u0131m\u0131z\u0131 varsayal\u0131m;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npublic class Order\r\n{\r\n    public int Id { get; set; }\r\n    public required string Contents { get; set; }\r\n    public required Address ShippingAddress { get; set; }\r\n    public required Address BillingAddress { get; set; }\r\n    public Customer Customer { get; set; } = null!;\r\n}\r\n<\/pre>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\npublic class Customer\r\n{\r\n    public int Id { get; set; }\r\n    public required string Name { get; set; }\r\n    public required Address Address { get; set; }\r\n    public List&lt;Order&gt; Orders { get; } = new();\r\n}\r\n<\/pre>\n<\/div>\n<p>\u015eimdi yap\u0131lan bu \u00e7al\u0131\u015fmay\u0131 Owned Types \u00f6zelli\u011fiyle yap\u0131land\u0131ral\u0131m ve devam\u0131nda a\u015fa\u011f\u0131daki sorguyu \u00e7al\u0131\u015ft\u0131r\u0131p neticeyi g\u00f6zlemleyelim;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    protected override void OnModelCreating(ModelBuilder modelBuilder)\r\n    {\r\n        modelBuilder.Entity&lt;Customer&gt;().OwnsOne(c =&gt; c.Address);\r\n        modelBuilder.Entity&lt;Order&gt;().OwnsOne(o =&gt; o.ShippingAddress);\r\n        modelBuilder.Entity&lt;Order&gt;().OwnsOne(o =&gt; o.BillingAddress);\r\n    }\r\n<\/pre>\n<\/div>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nCustomer customer = new()\r\n{\r\n    Name = &quot;Fezayi&quot;,\r\n    Address = new()\r\n    {\r\n        PostalCode = &quot;1000&quot;,\r\n        City = &quot;Yozgat&quot;,\r\n        Country = &quot;T\u00fcrkiye&quot;,\r\n        State = &quot;&quot;,\r\n        Street = &quot;&quot;\r\n    }\r\n};\r\nApplicationDbContext context = new();\r\nawait context.Customers.AddAsync(customer);\r\nawait context.SaveChangesAsync();\r\n<\/pre>\n<\/div>\n<p>Sonu\u00e7? Ba\u015far\u0131l\u0131, \u00f6yle de\u011fil mi! Ama benzer mant\u0131kla a\u015fa\u011f\u0131daki sorguyu \u00e7al\u0131\u015ft\u0131r\u0131rsak;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nApplicationDbContext context = new();\r\n\r\nCustomer? customer = await context.Customers.FindAsync(2);\r\ncustomer.Orders.Add(new()\r\n{\r\n    Contents = &quot;Kuru \u00dcz\u00fcm&quot;,\r\n    BillingAddress = customer.Address,\r\n    ShippingAddress = customer.Address,\r\n});\r\n\r\nawait context.SaveChangesAsync();\r\n<\/pre>\n<\/div>\n<p>a\u015fa\u011f\u0131daki hatayla kar\u015f\u0131la\u015f\u0131r\u0131z!<\/p>\n<div style=\"text-align:center;font-size:12px;line-height: 18px;color:red;\">System.InvalidOperationException: &#8216;Cannot save instance of &#8216;Order.ShippingAddress#Address (Address)&#8217; because it is an owned entity without any reference to its owner. Owned entities can only be saved as part of an aggregate also including the owner entity.&#8217;<\/div>\n<p>\n\u0130\u015fte burada g\u00f6r\u00fcld\u00fc\u011f\u00fc \u00fczere, Owned Types \u00f6zelli\u011finin yetersizli\u011fiyle kar\u015f\u0131la\u015f\u0131yoruz. \u00c7\u00fcnk\u00fc, bir entity par\u00e7as\u0131n\u0131 farkl\u0131 bir entity&#8217;de kullanmay\u0131 Owned Types \u00f6zelli\u011fiyle ger\u00e7ekle\u015ftirmeye \u00e7al\u0131\u015f\u0131rsak bu pek m\u00fcmk\u00fcn de\u011fildir!<\/p>\n<p>Art\u0131k bu tarz bir duruma kar\u015f\u0131n Complex Types \u00f6zelli\u011fiyle m\u00fcdahalede bulunabilmekte ve gayemizi ger\u00e7ekle\u015ftirebilmekteyiz.<\/p>\n<p>Bunun i\u00e7in ya model yap\u0131land\u0131rmas\u0131n\u0131 a\u015fa\u011f\u0131daki gibi Complex Type olarak \u015fekillendirmeli;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n    protected override void OnModelCreating(ModelBuilder modelBuilder)\r\n    {\r\n        modelBuilder.Entity&lt;Customer&gt;()\r\n            .ComplexProperty(e =&gt; e.Address);\r\n\r\n        modelBuilder.Entity&lt;Order&gt;(b =&gt;\r\n        {\r\n            b.ComplexProperty(e =&gt; e.BillingAddress);\r\n            b.ComplexProperty(e =&gt; e.ShippingAddress);\r\n        });\r\n    }\r\n<\/pre>\n<\/div>\n<p>ya da <code>ComplexType<\/code> attribute&#8217;undan faydalanmal\u0131d\u0131r;<\/p>\n<div style=\"font-size:12px;\">\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&#x5B;ComplexType]\r\npublic class Address\r\n{\r\n    public string Street { get; set; }\r\n    public string City { get; set; }\r\n    public string State { get; set; }\r\n    public string Country { get; set; }\r\n    public string PostalCode { get; set; }\r\n}\r\n<\/pre>\n<\/div>\n<p>B\u00f6ylece EF Core a\u00e7\u0131s\u0131ndan ciddi bir davran\u0131\u015fsal a\u00e7\u0131\u011f\u0131 kapatarak, ihtiya\u00e7 noktalar\u0131nda kullanabilmekteyiz.<\/p>\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, Bu i\u00e7eri\u011fimizde EF Core&#8217;da ki Owned Types \u00f6zelli\u011fine olduk\u00e7a benzerlik g\u00f6steren ve biz geli\u015ftiriciler a\u00e7\u0131s\u0131ndan bir entity i\u00e7erisindeki property&#8217;lerin d\u00fczenlenmesine olanak tan\u0131yan Complex Types \u00f6zelli\u011fini inceliyor olaca\u011f\u0131z. \u00d6ncelikle Owned Types \u00f6zelli\u011fini hat\u0131rlayarak ba\u015flayal\u0131m&#8230;&#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":11538,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5094,2914],"tags":[5097,5095,5098,963,2850,5096],"class_list":["post-27126","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ef-core-8","category-entity-framework-core","tag-complex-types","tag-ef-core-8","tag-ef-core-complex-types","tag-entity-framework","tag-entity-framework-core","tag-entity-framework-core-8"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27126","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=27126"}],"version-history":[{"count":4,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27126\/revisions"}],"predecessor-version":[{"id":27130,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/posts\/27126\/revisions\/27130"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media\/11538"}],"wp:attachment":[{"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/media?parent=27126"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/categories?post=27126"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gencayyildiz.com\/blog\/wp-json\/wp\/v2\/tags?post=27126"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}