6 Stimmen

Eindeutige Einschränkung mit EFCodeFirst und SqlCe4

Ich schreibe eine ASP.net MVC3-Anwendung mit Entity Framework Code First und SqlCe4.

Ich habe mehrere Modelle entworfen und eines gefunden, das sich als interessant erweist. Das ist, was ich bis jetzt habe:

public class Preference
    {
        public int PreferenceId { get; set; }

        [Required]
        public int StudentId { get; set; }
        public virtual Student Student { get; set; }

        [Required]
        public int PresentationId { get; set; }
        public virtual Presentation Presentation { get; set; }

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

Ich benötige jedoch eine eindeutige Einschränkung oder einen Index, da ich möchte, dass ein bestimmter Schüler eine Liste von Vorlieben hat, aber die PresentationId muss für jeden Schüler eindeutig sein. Gibt es eine Möglichkeit, dies über Code First oder ein Validierungsattribut zu erreichen?

Das hört sich so an, als würde ich den Zweig einer Viele-zu-Viele-Beziehung mit dem Preference-Objekt als Vermittler beschreiten, um die Eigenschaft Rank hinzuzufügen. Ich kann jedoch nicht finden, wie ich sicherstellen kann, dass die Werte eindeutig sind. Ist es wirklich der beste Weg, manuell einen eindeutigen Index zur Datenbank außerhalb von EF hinzuzufügen?

3voto

Eranga Punkte 31803

Derzeit (d.h. EF 4.1) hat EF keine Attribute oder Konfigurationsmechanismus zur Erstellung eindeutiger Indizes.

Wenn Sie jedoch den Database Initializer verwenden, können Sie ihn manuell erstellen

public class MyInitializer : IDatabaseInitializer<MyContext>
{
    public void InitializeDatabase(MyContext context)
    {
        if (!context.Database.Exists() || !context.Database.ModelMatchesDatabase())
        {
            context.Database.DeleteIfExists();
            context.Database.Create();

            context.ObjectContext.ExecuteStoreCommand("CREATE INDEX IX_Preference_PresentationId ON Preference ( PresentationId )");
        }
    }
}

Oder führen Sie ihn außerhalb des Initializers aus.

1voto

bwerks Punkte 8323

Ich bin mir nicht sicher, wie lange es diese Funktion schon gibt, aber in EF5 können Sie die CreateIndex- und DropIndex-Methoden in Ihren Up()- und Down()-Methoden verwenden. Damit können Sie eindeutige Indizes erstellen, die fast genauso funktionieren wie eindeutige Beschränkungen in der EF-eigenen Sprache.

public partial class UniqueIndexMigration
{
    public override void Up()
    {
        // Create new unique index
        this.CreateIndex("dbo.TableName", new[] { "Col1", "Col2", "Col3" }, true, "IX_TableName_Col1_Col2_Col3");
    }

    public override void Down()
    {
        // Drop unique index
        this.DropIndex("dbo.TableName", "IX_TableName_Col1_Col2_Col3");
    }
}

Das oben gezeigte true ist der Parameter, der angibt, dass es sich um eine eindeutige Einschränkung handelt. Leider werden diese Einschränkungen bei späteren Migrationen nicht beachtet (EF lässt sie nicht für Sie fallen, wenn Sie das zugrunde liegende Schema ändern), aber ich hoffe, dass Ihr Code durch die Verwendung der EF-API ein kostenloses Upgrade erhält, wenn diese Funktion endlich hinzugefügt wird.

0voto

mandreko Punkte 1706

In Anlehnung an das, was Eranga gesagt hat, habe ich es so ähnlich gemacht, aber so:

Ich habe den folgenden Code in meiner DataContext-Klasse verwendet:

public class StudentRegistrationContext : DbContext
{
    public StudentRegistrationContext()
    {
        Database.SetInitializer(new StudentRegistrationDatabaseInitializer());
    }

    public DbSet<Student> Students { get; set; }
    public DbSet<Teacher> Teachers { get; set; }
    public DbSet<Presenter> Presenters { get; set; }
    public DbSet<Presentation> Presentations { get; set; }
}

In der Klasse Database Initializer habe ich folgendes verwendet:

public class StudentRegistrationDatabaseInitializer : DropCreateDatabaseIfModelChanges<StudentRegistrationContext>
{
    protected override void Seed(StudentRegistrationContext context)
    {
        base.Seed(context);
        context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX UX_Preferences_StudentId_PresentationId ON Preferences (StudentId, PresentationId)");
    }
}

0voto

Joao Leme Punkte 9265

Siehe answear, das die Unique-Beschränkung mit einem Custom ValidationAttribute implementiert: https://stackoverflow.com/a/10566485/1133338

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X