Nullable Eigenschaft für Entitätsfeld, Entity Framework über Code First

77

Verwenden Sie die Datenanmerkung Requiredwie folgt:

[Required]
public int somefield {get; set;}

Setzt ein Feld auf Not Nullin der Datenbank. Wie kann ich ein Feld festlegen , um NULL- Werte zuzulassen? Ich habe versucht, es über SQL Server Management Studio festzulegen, aber Entity Framework hat es zurückgesetzt Not Null.

Chrisramon
quelle
7
Ich habe tatsächlich gesucht, um herauszufinden, wie CodeFirst NOT NULL ausführen kann, und Ihre Frage hat sie perfekt beantwortet! Danke :)
Andy Clarke

Antworten:

119

Lassen Sie einfach das Attribut [Erforderlich] in der string somefieldEigenschaft weg . Dadurch wird eine NULLfähige Spalte in der Datenbank erstellt.

Damit int-Typen NULL-Werte in der Datenbank zulassen, müssen sie im Modell als nullfähige Ints deklariert werden:

// an int can never be null, so it will be created as NOT NULL in db
public int someintfield { get; set; }

// to have a nullable int, you need to declare it as an int?
// or as a System.Nullable<int>
public int? somenullableintfield { get; set; }
public System.Nullable<int> someothernullableintfield { get; set; }
danludwig
quelle
5
In Ihrer Frage ist Ihre Eigenschaft eine Zeichenfolge. Damit ein Int Nullen zulässt, müssen Sie es wie folgt als nullbares Int deklarieren:public int? somenullableintfield { get; set; }
danludwig
Ja, mein Fehler, ich muss null für int-Typen zulassen.
Chrisramon
2
Was ist mit der Situation (Randfall, aber einer, mit dem ich konfrontiert bin)? Die Attribute werden für die Validierung von Geschäftsregeln und die Benutzerfreundlichkeit mit mvc verwendet, müssen es dem Benutzer jedoch ermöglichen, teilweise ausgefüllte Formulare zu speichern (dh lange Formulare, die eine Weile dauern können) machen). Ich muss in der Lage sein, EF zu erlauben, Spalten zu erstellen, die Nullen erlauben. Ich schätze, es ist der Modebuilder, der beim Erstellen verwendet wird, aber ich weiß nicht wie
Jon
Was passiert, wenn Sie [Erforderlich] auf eine nullfähige Eigenschaft wie "public int? somenullableintfield {get; set;}" setzen?
AXMIM
@AXMIM ... etwas spät ... aber [Erforderlich] Datenanmerkung überschreibt int?.
Chris Catignani
31

Die andere Option besteht darin, EF anzuweisen, dass die Spalte null sein soll:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
        modelBuilder.Entity<SomeObject>().Property(m => m.somefield).IsOptional();            
        base.OnModelCreating(modelBuilder);
}

Dieser Code sollte sich in dem Objekt befinden, von dem erbt DbContext.

Jon
quelle
1
Perfekt danke. Dies löste mein Problem mit [Erforderlichen] Zeichenfolgen, sodass sie in der Datenbank null sein konnten, aber eine Anforderung in MVC-Helfern erzwang
Derrick
2
Warum verwenden Sie keine ViewModels? Dann könnte es im Ansichtsmodell erforderlich sein und im realen Modell nicht.
Roel
Es ist möglicherweise Teil des Modells und des Ansichtsmodells, aber ein optionales Feld, das auf einer Geschäftslogik basiert. Danludwigs Antwort ist die vollständigere Lösung ( stackoverflow.com/a/10710934/6486 )
Jon
8

In Ef .net Core gibt es zwei Möglichkeiten, die Sie ausführen können. zuerst mit Datenanmerkungen:

public class Blog
{
    public int BlogId { get; set; }
    [Required]
    public string Url { get; set; }
}

Oder mit fließender API:

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property(b => b.Url)
            .IsRequired(false)//optinal case
            .IsRequired()//required case
            ;
    }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

Weitere Details finden Sie hier

nzrytmn
quelle
1
Im Fall von EF Core ist dies die Antwort, die funktioniert.
joanlofe
4

Jons Antwort hat bei mir nicht funktioniert, da ich einen Compilerfehler erhalten habe. CS0453 C # Der Typ muss ein nicht nullbarer Werttyp sein, um ihn als Parameter 'T' im generischen Typ oder in der generischen Methode zu verwenden

Das hat aber bei mir funktioniert:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<SomeObject>().HasOptional(m => m.somefield);
    base.OnModelCreating(modelBuilder);
}
Jon
quelle