wake-up-neo.com

Wie kann ich angeben, dass eine Eigenschaft eine TEXT-Spalte und nicht eine Nvarchar (4000) generiert

Ich arbeite mit der Code First-Funktion von Entity Framework und versuche herauszufinden, wie ich die Spaltendatentypen angeben kann, die erstellt werden sollen, wenn die Datenbank automatisch generiert wird.

Ich habe ein einfaches Modell:

public class Article
{
    public int ArticleID { get; set; }

    public string Title { get; set; }
    public string Author { get; set; }
    public string Summary { get; set; }
    public string SummaryHtml { get; set; }
    public string Body { get; set; }
    public string BodyHtml { get; set; }
    public string Slug { get; set; }

    public DateTime Published { get; set; }
    public DateTime Updated { get; set; }

    public virtual ICollection<Comment> Comments { get; set; }
}

Beim Ausführen meiner Anwendung wird automatisch eine SQL CE 4.0-Datenbank mit dem folgenden Schema erstellt:

DB Schema

So weit, ist es gut! Die Daten, die ich in die Eigenschaften Body und BodyHtml einfügen werde, sind jedoch routinemäßig größer als die maximal zulässige Länge für den Spaltentyp NVarChar. Ich möchte, dass EF Text-Spalten für diese Eigenschaften generiert.

Ich kann jedoch keinen Weg finden, dies zu tun! Nach einigem Googeln und Lesen habe ich versucht, den Spaltentyp mit DataAnnotations aus den Informationen in diese Antwort anzugeben:

using System.ComponentModel.DataAnnotations;

...

[Column(TypeName = "Text")]
public string Body { get; set; }

Dies löst die folgende Ausnahme aus (wenn die Datenbank gelöscht wird und die App erneut ausgeführt wird):

Schema specified is not valid. Errors: (12,6) : error 0040: The Type text is not qualified with a namespace or alias. Only PrimitiveTypes can be used without qualification.

Ich habe jedoch keine Ahnung, welchen Namespace oder Alias ​​ich angeben sollte, und ich konnte nichts finden, was mir sagen würde.

Ich habe auch versucht, die Annotation gemäß diese Referenz zu ändern. _:

using System.Data.Linq.Mapping;

...

[Column(DbType = "Text")]
public string Body { get; set; }

In diesem Fall wird eine Datenbank erstellt, aber die Spalte Body ist immer noch eine NVarChar(4000). Es scheint also, dass Annotationen ignoriert werden.

Kann jemand helfen? Dies scheint eine ziemlich allgemeine Anforderung zu sein, aber meine Suche war erfolglos!

49
Mark Bell

Ich schätze die Anstrengung, die in die vorhandene Antwort gesteckt wurde, aber ich habe nicht die Antwort auf die Frage gefunden ... also habe ich das getestet und herausgefunden

[Column(TypeName = "ntext")]
public string Body { get; set; }

(die von System.ComponentModel.DataAnnotations) erstellt eine Spalte vom Typ ntext.

(Mein Problem mit der akzeptierten Antwort ist, dass es den Anschein hat, dass Sie den Spaltentyp in der Benutzeroberfläche ändern sollten, aber die Frage ist, wie Sie dies programmgesteuert tun.)

69
Marcel Popescu

Sie können die folgende DataAnnotation verwenden, und Code-First generiert den maximal zulässigen Datentyp der Datenbank. Im Fall von Sql CE ergibt sich eine darunterliegende ntext-Spalte.

[MaxLength]

oder die EF 4.1 RC fließende API verwenden ...

protected override void OnModelCreating(ModelBuilder modelBuilder){
    modelBuilder.Entity<Article>()
        .Property(p => p.Body)
        .IsMaxLength();
}
28
Michael

Haben Sie ntext ausprobiert? Ich habe gerade eine SQL CE 4.0-Datenbank erstellt. Wenn ich einer Tabelle manuell eine Spalte hinzufüge, stelle ich fest, dass text nicht in der Liste der Datentypen verfügbar ist, während ntext ist. Genauso wie Sie nvarchar auswählen können, aber keine varchar.

Leider ist die größte nvarchar-Größe, die Sie auswählen können, 4000. Daher ist nvarchar(max) keine Option.

There is ntext but no text

9
Kristof Claes

Das Problem bei der Verwendung des Zeichenfolgenlängenattributs, z.

[StringLength(4010)]

Ist jede Zeichenfolge> die Anzahl der im Attribut definierten Zeichen löst eine Überprüfungsausnahme aus. Dies ist ein Grund, warum Sie eine nicht definierte Feldgröße für eine Spalte verwenden würden, oder Sie verwenden eine große Zahl im Attribut und verlieren jede durch das Attribut angebotene Validierung. Letztendlich verwenden Sie einen Validierungsmechanismus, um ein Mapping-Problem zu lösen, wenn Sie das StringLength-Attribut verwenden. Die Antwort von Marcel Popescu mit dem Column-Attribut ist eine viel bessere Lösung, da die Mapping-Attribute zur Definition des Typs verwendet werden und Sie dennoch verwenden können das StringLength-Attribut zur Überprüfung.

Eine andere Option ist die Verwendung der EF4-CTP5-API für fließende Informationen und die Definition der Spaltenzuordnung im Ereignis OnModelCreating im DbContext, z.

protected override void OnModelCreating(ModelBuilder modelBuilder){
    modelBuilder.Entity<Article>()
    .Property(p => p.Body)
    .HasColumnType("nvarchar(max)");
}

Es sollte auch beachtet werden, dass NText ein veralteter Datentyp ist ( ntext, text und image (Transact-SQL) - MS-Onlinedokumentation ). Es wird empfohlen, stattdessen NVarChar (MAX) zu verwenden

6
nakchak

Ich weiß, das ist wahrscheinlich ein Jahr zu spät, aber: 

Benutzen:

[StringLength(-1)] 

Dadurch wird ein nText-Feld erstellt. Es ist mir gelungen, mindestens 25 KByte in diesem Feld mit der Compact Edition 4.0-Datenbank zu speichern. 

5
Johan Plogfeldt

Sie können System.ComponentModel.DataAnnotations.Schema.ColumnAttribute verwenden.

[Column(TypeName="text")]
public string Text { get; set; }

oder über Fluent API:

modelBuilder.Entity<YourEntityTypeHere>()
    .Property( e => e.Text)
    .HasColumnType("text");
4
Moes

Stimmen Sie zu, dass TypeName = "ntext" zu funktionieren scheint, obwohl ich auch hinzufügen muss:

[StringLength(Int32.MaxValue)]

um zu verhindern, dass die voreingestellte Stringlänge von 128 im Weg ist.

1
Steve Owen

Haben Sie Kleinbuchstaben "text" ausprobiert? Gemäß dieser MSDN-Diskussion unterscheidet der Datenanbieter zwischen Groß- und Kleinschreibung.

1
Axarydax

Diese DataAnnotation bewirkt, dass Code-First auch eine Nvarchar (MAX) -Spalte in SQL generiert :)

[StringLength(4010)]
1
Bohdan Lyzanets

Diese DataAnnotation veranlasst Code-First, eine nvarchar (MAX) -Spalte in SQL zu generieren

[StringLength(1073741822)]

Nicht sicher, ob andere große Zahlen dasselbe tun ... Ich habe diese mit dem Taschenrechner und der NVARAR-Spezifikation (MAX) erhalten.

Ich habe es mit SQL Server 2005 Express oder nicht versucht, aber nicht mit CE

Ich benutze es und es funktioniert, aber ich würde gerne wissen, ob es eine gute Idee ist oder ob mir etwas fehlt. Gibt es eine andere Möglichkeit, Code zu erstellen, um zu wissen, dass ich nvarchar (MAX) will?

1
Peto

Wenn Sie nicht alle Ihre Eigenschaften kommentieren möchten und eine zeitgenössische EF verwenden, verwenden Sie eine Konvention:

public class StringNTextConvention : Convention {
  public StringNTextConvention() {
    Properties<string>().Configure(p => p.HasColumnType("ntext"));                    
  }
}

Sie können es von Ihrer onModelCreating() aus aufrufen:

modelBuilder.Conventions.Add(new StringNTextConvention());

und alle Ihre strings werden automatisch in ntext-Spalten umgewandelt.

1
Gábor

Falls Sie die Migration und die Update-Datenbank mit Package Manager hinzufügen, können Sie die Erstellungstabelle durch Hinzufügen von storeType wie folgt ändern:

       CreateTable(
            "dbo.Table_Name",
            c => new
                {
                    ID = c.Int(nullable: false, identity: true),
                    Title = c.String(nullable: false, maxLength: 500),
                    Body = c.String(unicode: false, storeType: "ntext"),
                })
            .PrimaryKey(t => t.ID);
0
hsobhy