2013-09-18 2 views
11

Я изучаю Entity Framework (в настоящее время использую бета-версию EF6), и я использую первый шаблон кода в существующей базе данных. Объекты и класс DbContext создаются автоматически с использованием шаблона T4.Как предотвратить изменение базы данных DbContext?

Я хотел бы предотвратить создание или изменение чего-либо в базе данных во время выполнения.

Как я могу это сделать?

+1

Как вы создали базу данных? EF Code Сначала по умолчанию добавляет таблицу в базу данных, чтобы узнать, изменилась ли ваша модель. Если база данных не была решена с помощью codefirst/migrations, данных в db нет, и EF не коснется схемы базы данных. Если вы говорите о данных - в любое время вы вызываете .SaveChanges() данные в db могут быть добавлены/изменены/удалены – Pawel

+0

Я не занимаюсь разработкой структуры базы данных. Мне нужно, чтобы мой код работал с ним, как есть. NO NO WAY я могу позволить ему изменять объекты. Я попробовал первый подход к базе данных, но нашел его очень ограниченным. Мне нужно иметь возможность передавать случайные объекты соединения в контекст, и БД сначала, похоже, не позволяла этого. – Crono

+1

CodeFirst не изменит вашу базу данных, если она не создала ее. – Pawel

ответ

9

Когда вы Enable-Миграция команды, вам будут представлены с папкой /Миграции, под которым вы можете найти файл с именем Configuration.cs. В конструкторе этого файла, по умолчанию, это свойство установлено в значение:

AutomaticMigrationsEnabled = false; 

Какой будет гарантировать, что ваша база данных не будут перенесены автоматически, а путем вызова каждой миграции вручную.

Однако, если ваша база данных больше, чем ваши модели домена, т.е. вы работаете только с частью уже существующей базы данных, то где-то в вашем приложении запускается (если это приложение ASP.NET, Application_Start обработчик событий), вам необходимо добавить следующий код:

Database.SetInitializer<YourDbContext>(null); 

в противном случае, Entity Framework будет жаловаться, что существует несоответствие между определением базы данных в вашей модели предметной области и фактического состояния текущей базы данных.

EDIT:

Если вы хотите быть уверены, что YourDbContext не пытается изменить базу данных, сделайте следующее:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    throw new YourCustomException("Code first changes are not allowed."); 
} 

EDIT снова:

Я пытаюсь чтобы понять, какой сценарий вы пытаетесь выполнить. Если у вас есть существующая база данных, и вы хотите обновить его, но только вручную, этот подход:

  1. Используйте DbContext шаблон генератор для создания DbContext и объектов из существующей базы данных.
  2. Run Enable-Миграция
  3. ли надстройка миграции Initial
  4. Шаг 3 должен генерировать пустую миграцию, если все было сделано правильно . Вы можете удалить его.
  5. Теперь, когда вы делаете какое-то изменение, вам нужно добавить-перенаправление ChangeName. Это не будет работать в базе данных, если вы не сделаете обновленную базу данных.
+0

Если я выбрал исключение в методе OnModelCreating, то где еще я могу определить конфигурацию с помощью свободного api? – Crono

+1

Хорошо, я пытаюсь понять, что вы пытаетесь сделать. Я снова отредактировал свой пост, посмотрю, если это имеет смысл для вас сейчас. –

+0

Как я уже сказал, у меня есть шаблон T4, который генерирует сущности и DbContext. Мне нужно это, так как я требую именования и интерфейсов, которые необходимо выполнить. Генератор по умолчанию не дал мне эффективного способа, чтобы это произошло (если я не настолько уверен в том, как это работает). Тем не менее, я думаю, что ваш ответ вполне закончен, поэтому я буду отмечать его как принятый. Большое вам спасибо за вашу помощь. :) – Crono

3

Установите инициализатор для вашего контекста на null.

Это должно оставить базу данных в ее существующем состоянии при запуске приложения.

Обратите внимание, что при попытке запустить приложение после изменения класса dbContext и/или схемы базы данных вы получите исключение, поскольку ваша схема базы данных больше не будет соответствовать ожидаемому контексту.

+0

Я прав, что я не могу помешать любой другой сборке, ссылающейся на сборку контекста, изменить ее инициализатор? Мне это действительно не нравится. :(Мне жаль, что я не могу исключить исключение из SaveChanges, если контекст задан таким образом, что изменения базы данных разрешены. Предположите, что это не предназначено для использования. – Crono

+1

Если вы обеспокоены структурой базы данных, вы можете просто изменить строку подключения для своего контекста на тот, который не дает ему создавать/изменять привилегии таблицы. Если вы обеспокоены изменением содержимого существующих таблиц, вы можете использовать строку подключения, которая прочитала только разрешения для таблиц, которые вы хотите защитить. Редактирование: чтобы уточнить, вам нужно будет настроить новые (ограниченные) учетные записи на вашем SQL-сервере и изменить свои строки подключения, чтобы вы подключались с помощью этих учетных записей. – ThinTim

+0

Чтобы решить эту проблему: Я хотел бы создать исключение в SaveChanges, если контекст установлен таким образом, что изменения базы данных разрешены. », Я изменил свой пост. Проверьте решение между EDIT, это может помочь вам. –

0

У меня была эта проблема с DBFirst и EF 6.1, она создавала новую таблицу на основе EntityName. Поэтому я изменил виртуальный метод OnModelCreating для отображения моих таблиц.

Итак, если EntityName было названо MyStuffs, поскольку по умолчанию имена EnitityNames имеют множественность, которые у вас есть, чтобы отменить выбор этого во время генерации EF. В моем случае мастер создавал множественную версию таблицы.

public class MyContext: DbContext 
{ 
    public MyContext() 
     : base("name=MyEntityConnectionName") 
    { 
    } 
    public MyContext(string connectionString) 
     : base(connectionString) 
    { 
    } 
    #region methods 

    public static MyContext Create() 
    { 
     return new MyContext(); 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 
     // Map Entities to their tables. 
     modelBuilder.Entity<MyModel>().ToTable("MyStuff"); //prevent a new table from being added since we added a mapping 
    } 

    #endregion 
    public virtual DbSet<MyModel> MyEntities{ get; set; } 
} 
Смежные вопросы