{"id":80,"date":"2019-01-15T12:21:45","date_gmt":"2019-01-15T11:21:45","guid":{"rendered":"https:\/\/wissing.me\/daan\/blog\/?p=80"},"modified":"2019-01-15T12:21:45","modified_gmt":"2019-01-15T11:21:45","slug":"entity-framework-and-calculated-properties","status":"publish","type":"post","link":"https:\/\/daan.wsng.eu\/index.php\/2019\/01\/15\/entity-framework-and-calculated-properties\/","title":{"rendered":"Entity Framework and calculated properties"},"content":{"rendered":"<p>Oh, the joys of legacy. Decisions were made, nobody knows why and now you &#8220;just&#8221; have to work with it. Today was one of those days.It is not as bad as I&#8217;ve seen before (Hello critical Visual Basic 6 code), but still. Having an awesome quality tool like <a href=\"https:\/\/www.sonarqube.org\/\">SonarQube<\/a> regularly scanning your solutions will catch a lot of things you did not think of before. This time, it was a non-standard use of property setter:<\/p>\n<p><img loading=\"lazy\" class=\"alignnone wp-image-82 size-full\" src=\"https:\/\/wissing.me\/daan\/blog\/wp-content\/uploads\/sonarqubewarning.png\" alt=\"\" width=\"825\" height=\"240\" srcset=\"https:\/\/daan.wsng.eu\/wp-content\/uploads\/sonarqubewarning.png 825w, https:\/\/daan.wsng.eu\/wp-content\/uploads\/sonarqubewarning-300x87.png 300w, https:\/\/daan.wsng.eu\/wp-content\/uploads\/sonarqubewarning-768x223.png 768w\" sizes=\"(max-width: 825px) 100vw, 825px\" \/><\/p>\n<p>Yes, this is weird and not intuitive to have a setter for a calculated property that doesn&#8217;t do anything. So, my first instinct was to remove the setter all together, since it is not needed. Great, warning gone, lets move on.<\/p>\n<p>&#8230;Or maybe not. On the next item, I needed to make a new migration, and to my surprise the following lines were included:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic override void Up()\r\n{\r\n    DropColumn(&quot;CM.tbl_ProcesstatusBenaderstap&quot;, &quot;AantalNietInAanmerking&quot;);\r\n}\r\n<\/pre>\n<p>Oops. The properties are actually stored in the database (one of those decisions&#8230;), so this is not what I want. Apparently Entity Framework Code First migrations really needs the setter to determine that yes, we really want to store this value in the database.<\/p>\n<p>SonarQube gives us the tip to use <code>throw new InvalidOperationException()<\/code> in the setter, so let&#8217;s try that solution. Yay, migration allows it and the column is no longer dropped. However, when retrieving the entity from the database, the exception does get thrown&#8230; so unfortunately it&#8217;s not an option.<\/p>\n<figure id=\"attachment_81\" aria-describedby=\"caption-attachment-81\" style=\"width: 701px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" class=\"wp-image-81 size-full\" src=\"https:\/\/wissing.me\/daan\/blog\/wp-content\/uploads\/invalidoperation.png\" alt=\"\" width=\"701\" height=\"392\" srcset=\"https:\/\/daan.wsng.eu\/wp-content\/uploads\/invalidoperation.png 701w, https:\/\/daan.wsng.eu\/wp-content\/uploads\/invalidoperation-300x168.png 300w\" sizes=\"(max-width: 701px) 100vw, 701px\" \/><figcaption id=\"caption-attachment-81\" class=\"wp-caption-text\">Entity Framework trying to set my property&#8230; by using the setter<\/figcaption><\/figure>\n<p>OK, moving on. Maybe there is a way to signal to Entity Framework that yes, we do want to store this variable, but not have a setter. Like using the inverse of the <code>[NotMapped]<\/code> attribute. Maybe using the <code>[Column]<\/code> attribute on the property works? But alas, the column is still removed in the migration.<\/p>\n<p>How about using <a href=\"https:\/\/docs.microsoft.com\/en-us\/ef\/core\/modeling\/backing-field\">backing fields<\/a>? Sure, its actually a thing for Entity Framework Core, but we can build our own version, right?<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nprivate int _aantalNietInAanmerking;\r\n\r\npublic int AantalNietInAanmerking\r\n{\r\n    get\r\n    {\r\n        return this.AantalNietGeselecteerd + this.AantalGeblokkeerd;\r\n    }\r\n    private set { this._aantalNietInAanmerking = value; }\r\n}\r\n<\/pre>\n<p>Ok, that looks like something, the column still exists in the migration. But now I&#8217;m getting warnings about a private field that should only be used as a local variable. Plus, it still looks like a code smell, having a private field just for storing the value that was in the database. The longer I look at it, the more I dislike it. What is the most elegant solution? I need the setter to be there for Entity Framework, but I don&#8217;t want anybody to actually use it. So I made the following compromise:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic int AantalNietInAanmerking\r\n{\r\n    get\r\n    {\r\n        return this.AantalNietGeselecteerd + this.AantalGeblokkeerd;\r\n    }\r\n    private set\r\n    {                \r\n        \/\/ Set is nodig voor migratie\r\n    }\r\n}\r\n<\/pre>\n<p>I guess I can live with this now. The warning is still there in SonarQube, but the code is only actually usable in the constructor and by EntityFramework, so I think it will be good enough for now.<\/p>\n<p>(Also, please don&#8217;t roast me for the Dutch language used in the code. Another one of those requirements&#8230;)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Oh, the joys of legacy. Decisions were made, nobody knows why and now you &#8220;just&#8221; have to work with it. Today was one of those days.It is not as bad as I&#8217;ve seen before (Hello critical Visual Basic 6 code), but still. Having an awesome quality tool like SonarQube regularly scanning your solutions will catch&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"twitterCardType":"","cardImageID":0,"cardImage":"","cardTitle":"","cardDesc":"","cardImageAlt":"","cardPlayer":"","cardPlayerWidth":0,"cardPlayerHeight":0,"cardPlayerStream":"","cardPlayerCodec":""},"categories":[9,4],"tags":[],"_links":{"self":[{"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/posts\/80"}],"collection":[{"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/comments?post=80"}],"version-history":[{"count":5,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/posts\/80\/revisions"}],"predecessor-version":[{"id":87,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/posts\/80\/revisions\/87"}],"wp:attachment":[{"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/media?parent=80"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/categories?post=80"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/tags?post=80"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}