Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework 7 Fluent API Doesn't Recognize IsOptional()

I'm currently setting up my database in my Asp.Net 5 project using entity framework 7, previously with EF 6, when I wanted to make some of my columns nullable, I would use:

modelBuilder.Entity<Article>().Property(t => t.ArticleDateModified).IsOptional();

But it seems that IsOptional is not part of EF7 anymore, I was wondering how can I achieve the same thing using EF7?

Edit: Marc's answer is indeed correct, first I though it worked because I found something that was like IsOptional:

builder.Entity<Article>().Property(t => t.ArticleDateModified).IsRequired(false);

But after I ran some test without it, it set the database column nullable because I marked it as nullable in my domain model:

public DateTime? ArticleDateModified { get; set; }

Also worth to note that when I made the DateTime non-nullable and used the IsRequired(false), I got the following error:

The property 'ArticleDateModified' on entity type 'Article' cannot be marked as nullable/optional because the type of the property is 'DateTime' which is not a nullable type. Any property can be marked as non-nullable/required, but only properties of nullable types and which are not part of primary key can be marked as nullable/optional.

so, I wonder what is the use of IsRequired(false) here if all I have to do to make a database column nullable is to make it nullable in my domain class?

like image 387
Hamid Mosalla Avatar asked Dec 22 '15 05:12

Hamid Mosalla


1 Answers

Based on the note in this documentation page, it would appear that support for doing this declaratively was rescinded. To wit:

A property whose CLR type cannot contain null cannot be configured as optional. The property will always be considered required by Entity Framework.

That this was intentional can be seen in the design discussions from the project hosting on GitHub, specifically:

That is, a property marked as nullable supports null values, while a property marked as non-nullable must never contain null values. It follows from this that marking a property which is of a non-nullable CLR type as allowing nulls will not be allowed. This is different from the EF6 behavior where this is allowed. [emphasis added]


The upshot is, in EF7 a NULL column strictly implies a nullable mapped property. If your property is nullable, the associated column must be NULL unless you mark or configure it with IsRequired.


Response to OP edits

That's interesting, I didn't initially see the documentation on an IsRequired(bool) API. I found a discussion point on it in some June meeting notes that state that this would be the equivalent of EF6's IsOptional():

.IsOptional() - We'll provide this functionality via calling Required(false)
.IsRequired() - Provide Required() with the same functionality

Even though this was the original intent, the design decision to rescind support dates from October. (Per update) attempting to set IsRequired(false) on a non-nullable property results in a run-time error, rather than having been removed entirely.

Though now superfluous, the API cannot be removed without breaking valid code: it wasn't implemented with separate IsRequired(bool) and IsRequired() definitions, but with a single IsRequired(bool required = true). If it were removed and replaced with the parameterless version it would be a breaking change.

like image 164
Marc L. Avatar answered Sep 20 '22 14:09

Marc L.