Festlegen einer eindeutigen Einschränkung mit einer fließenden API?
184
Ich versuche, eine EF-Entität mit Code First und einer EntityTypeConfigurationfließenden API zu erstellen . Das Erstellen von Primärschlüsseln ist einfach, mit einer eindeutigen Einschränkung jedoch nicht. Ich habe alte Beiträge gesehen, in denen vorgeschlagen wurde, native SQL-Befehle auszuführen, aber die den Zweck zu vereiteln scheinen. ist das mit EF6 möglich?
Hier ist ein realistischeres Beispiel. Es fügt einen eindeutigen Index für mehrere Eigenschaften hinzu: User.FirstNameund User.LastNamemit dem Indexnamen "IX_FirstNameLastName"
Dies ist erforderlich, um die Spaltenanmerkung als "Index" zu benennen! Ich habe einen anderen Namen geschrieben und es hat nicht funktioniert! Ich habe Stunden damit verbracht, es wie in Ihrem Beitrag in den ursprünglichen "Index" umzubenennen, und habe verstanden, dass dies wichtig ist. :( Es muss eine Konstante im Framework geben, damit die Zeichenfolge nicht hart codiert wird.
Alexander Vasilyev
10
@ AlexanderVasilyev Die Konstante ist definiert alsIndexAnnotation.AnnotationName
Nathan
3
@ Nathan Danke! Das ist es! Das Beispiel in diesem Beitrag muss mit dieser Konstante korrigiert werden.
Alexander Vasilyev
2
Kann nicht scheinen, es in EF7 - DNX
Shimmy Weitzhandler
2
Ich glaube, dass IsUnique beim Erstellen von IndexAttribute im ersten Beispiel auf true gesetzt werden muss. So : new IndexAttribute() { IsUnique = true }. Andernfalls wird nur ein regulärer (nicht eindeutiger) Index erstellt.
Jakubka
134
Als Ergänzung zu Yorros Antwort kann dies auch mithilfe von Attributen erfolgen.
Beispiel für eine inteindeutige Tastenkombination:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace EFIndexTest{classProgram{staticvoidMain(string[] args){
using (var context =newAppDbContext()){var newUser =newUser{UniqueKeyIntPart1=1,UniqueKeyIntPart2=1,UniqueKeyStringPart1="A",UniqueKeyStringPart2="A"};
context.UserSet.Add(newUser);
context.SaveChanges();}}}[MetadataType(typeof(UserMetadata))]publicclassUser{publicintId{get;set;}publicintUniqueKeyIntPart1{get;set;}publicintUniqueKeyIntPart2{get;set;}publicstringUniqueKeyStringPart1{get;set;}publicstringUniqueKeyStringPart2{get;set;}}publicclassUserMetadata{[Index("IX_UniqueKeyInt",IsUnique=true,Order=1)]publicintUniqueKeyIntPart1{get;set;}[Index("IX_UniqueKeyInt",IsUnique=true,Order=2)]publicintUniqueKeyIntPart2{get;set;}[Index("IX_UniqueKeyString",IsUnique=true,Order=1)][MaxLength(50)]publicstringUniqueKeyStringPart1{get;set;}[Index("IX_UniqueKeyString",IsUnique=true,Order=2)][MaxLength(50)]publicstringUniqueKeyStringPart2{get;set;}}publicclassAppDbContext:DbContext{publicvirtualDbSet<User>UserSet{get;set;}}}
Nicht, wenn Sie Ihr Domain-Modell vollständig von Speicherproblemen trennen möchten.
Rickard Liljeberg
4
Sie müssen auch sicherstellen, dass Sie einen Verweis auf EntityFramework
Michael Tranchida
2
Seien Sie nett, wenn das Index-Attribut vom Entity Framework getrennt wurde, damit ich es in mein Models-Projekt aufnehmen kann. Ich verstehe, dass es sich um ein Speicherproblem handelt, aber der Hauptgrund, warum ich es verwende, besteht darin, Dinge wie Benutzernamen und Rollennamen eindeutig einzuschränken.
Sam
2
Kann nicht scheinen, es in EF7 - DNX
Shimmy Weitzhandler
4
Dies funktioniert nur, wenn Sie auch die Länge der Zeichenfolge einschränken, da SQL nicht zulässt, dass nvarchar (max) als Schlüssel verwendet wird.
JMK
17
Hier ist eine Erweiterungsmethode zum flüssigeren Festlegen eindeutiger Indizes:
Die Antwort von @ coni2k ist korrekt. Sie müssen jedoch ein [StringLength]Attribut hinzufügen , damit es funktioniert. Andernfalls wird eine ungültige Schlüsselausnahme angezeigt (Beispiel unten).
IndexAnnotation.AnnotationName
new IndexAttribute() { IsUnique = true }
. Andernfalls wird nur ein regulärer (nicht eindeutiger) Index erstellt.Als Ergänzung zu Yorros Antwort kann dies auch mithilfe von Attributen erfolgen.
Beispiel für eine
int
eindeutige Tastenkombination:Wenn der Datentyp ist
string
,MaxLength
muss das Attribut hinzugefügt werden:Wenn ein Problem mit der Trennung von Domäne und Speichermodell besteht, kann die Verwendung von
Metadatatype
Attribut / Klasse eine Option sein: https://msdn.microsoft.com/en-us/library/ff664465%28v=pandp.50%29.aspx?f= 255 & MSPPError = -2147217396Ein schnelles Beispiel für eine Konsolen-App:
quelle
Hier ist eine Erweiterungsmethode zum flüssigeren Festlegen eindeutiger Indizes:
Verwendung:
Erzeugt eine Migration wie:
Src: Erstellen eines eindeutigen Index mit der fließenden API von Entity Framework 6.1
quelle
Die Antwort von @ coni2k ist korrekt. Sie müssen jedoch ein
[StringLength]
Attribut hinzufügen , damit es funktioniert. Andernfalls wird eine ungültige Schlüsselausnahme angezeigt (Beispiel unten).quelle
Leider wird dies in Entity Framework nicht unterstützt. Es war auf der Roadmap für EF 6, wurde aber zurückgedrängt: Workitem 299: Unique Constraints (Unique Indexes)
quelle
quelle