简体   繁体   中英

EF5 Code First: Detect if it creates a database so I can run ALTER statements

I am new with Entity Framework 5. Our team is using Code First workflow.

Before I'll start with my main question, let me first show you what I have tried ( the ultimate comment of all time :D ) .

public class MyDBContext : CDBContext
{
    public MyDBContext() : base(connString) { }

    public MyDBContext(string connStr) : base(connStr) { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // removes some conventions
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
        // ........

        // model configurations which contains mappings
        modelBuilder.Configurations.Add(new AccountConfiguration());
        // ........

        // calls base OnModelCreating
        base.OnModelCreating(modelBuilder);
    }

    // list of all Entity
    public DbSet<Account> Account { get; set; }
}

MyDBContext is the class I have created that inherits from CBDContext that contains override methods and which also inherits from DBContext . One of the problems I have encountered is that entity framework doesn't handle field uniqueness. I have already read the article on Configuring/Mapping Properties and Types with the Fluent API on their site and I can't find any configuration to set a property into unique.

So what I did in order to set the field unique is to manually run several ALTER sql statements during creation,

using (MyDBContext _context = new MyDBContext(connString))
{
    if (_context.Database.CreateIfNotExists()) 
    {
        _context.Database.ExecuteSqlCommand("ALTER TABLE Account ADD CONSTRAINT UQ_Account_AccountNumber UNIQUE(AccountNumber)");
        _context.Database.ExecuteSqlCommand("ALTER TABLE Account ADD CONSTRAINT UQ_Account_GUID UNIQUE(GUID)");
        // .... more on this in the following lines ...
    }
}

My Questions:

  1. Am I right that entity framework don't have any configuration or data annotations to set the field unique ?
  2. Is there a way to detect or know during runtime if EF creates a database or not so I can move or hide this statement if (_context.Database.CreateIfNotExists()) somewhere to an available method that can be overriden?

What I really want is to remove if (_context.Database.CreateIfNotExists()) from the using statemnt and put it somewhere else or inside MyDBContext so my code will look like this,

using (MyDBContext _context = new MyDBContext(connString))
{
    Account _acc = new Account()
    // ...Account properties ...

    _context.Account.Add(_acc);
    _context.SaveChanges();
}

Thanks.

You should take a look at Code First Migrations , more specific at the Data Motion / Custom SQL and later sections - this is might the way to achieve your desired result. Your migration class can look like this:

public partial class AddUniqueConstrains : DbMigration
{
    public override void Up()
    {
        Sql("ALTER TABLE Account ADD CONSTRAINT UQ_Account_AccountNumber UNIQUE(AccountNumber)");
        Sql("ALTER TABLE Account ADD CONSTRAINT UQ_Account_GUID UNIQUE(GUID)");
    }

    public override void Down()
    {
        Sql("ALTER TABLE Account DROP CONSTRAINT UQ_Account_AccountNumber UNIQUE");
        Sql("ALTER TABLE Account DROP CONSTRAINT UQ_Account_GUID");
    }
}

You can also explore other options described in answers to this question: Unique Constraint in Entity Framework Code First

If you don't use (or cannot use) EF migrations you can use custom initializer as mentioned in this answer . The custom initializer will execute a Seed method after creating the database = only once when database doesn't exist. If you need to incrementally develop the database initializer itself will not help you (that is what migrations are for).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM