Попробуйте мое решение . Это предотвращает создание миграции для таблиц, помеченных как представления
kogoia
Ответы:
95
Если, как и я, вас интересует только сопоставление сущностей, поступающих из другой базы данных (в моем случае - erp), чтобы связать их с сущностями, специфичными для вашего приложения, то вы можете использовать представления, как вы используете таблицу (сопоставьте представление в так же!). Очевидно, что если вы попытаетесь обновить эти объекты, вы получите исключение, если представление не обновляется. Процедура такая же, как и в случае обычных (основанных на таблице) сущностей:
Создайте класс POCO для представления; например FooView
Добавьте свойство DbSet в класс DbContext
Используйте файл FooViewConfiguration, чтобы установить другое имя для представления (используя ToTable ("Foo"); в конструкторе) или установить определенные свойства
+1 за то, что не предполагал, что "Code First" == автоматическое создание базы данных
onetwopunch
3
@DaveJellison, не могли бы вы уточнить или предоставить ссылку для добавления представления как части IDatabaseInitializer
Ральф Шиллингтон
18
Это только я, или все получают пустую таблицу, созданную миграцией? Есть ли способ этого избежать?
Кремена Лалова
4
Просто убедитесь, что это решение потребовало от нас предварительного создания представления в базе данных SQL извне? Можно ли определить представление в коде и заполнить его в базе данных с помощью команды Add-Migration / Update-Database?
frostshoxx
6
Несколько вещей. 1. В этом ответе не упоминается, что вам нужно создать представление вручную с помощью SQL, это можно сделать с помощью миграции. 2. Вам не нужно настраивать имя представления, если имя класса совпадает с именем представления. 3. Вы можете использовать DataAnnotations следующим образом:, [Table("myView")]это, возможно, проще, чем создание EntityTypeConfiguration.
Rudey
23
Это может быть обновление, но для использования представлений с кодом EF сначала просто добавьте [Table ("NameOfView")] в начало класса, и все должно работать правильно, без необходимости проходить через все обручи, через которые проходят все остальные. Также вам нужно будет указать один из столбцов как [ключевой] столбец. Вот мой пример кода ниже для его реализации.
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespaceSomeProject.Data
{
[Table("SomeView")]
publicclassSomeView
{
[Key]
publicint NameID { get; set; }
publicstring Name { get; set; }
}
}
А вот как выглядит контекст
using System.Data.Entity;
namespaceSomeProject.Data
{
publicclassDatabaseContext : DbContext
{
public DbSet<SomeView> SomeViews { get; set; }
}
}
Это то же самое, что и принятый ответ, за исключением того, что в нем используются DataAnnotations, а в принятом ответе используется EF Fluid API.
Rudey
4
На самом деле нет. Я безуспешно пытался ответить на принятый ответ, и у меня это не сработало. Но тогда я использую миграции, так что это могло повлиять на вещи. Я обнаружил, что мне нужно сначала выполнить миграцию, ЗАТЕМ добавить мой класс представления, поскольку он уже существует в базе данных. Мы бы поступили точно так же, если бы у нас уже были существующие таблицы в базе данных. Поскольку представление представляет собой «виртуальную таблицу», синтаксис таблицы в Entity Framework по-прежнему работает.
Чарльз Оуэн
11
Если все, что вам нужно, это набор ненормализованных объектов, вы можете просто создать IQueryable<TDenormolized>в своем DbContextклассе общедоступное свойство только для получения .
В этом случае getвы возвращаете результат Linq для проецирования ненормализованных значений в ваши ненормализованные объекты. Это может быть лучше, чем писать представление БД, потому что вы программируете, вы не ограничены только использованием selectоператоров. Также это безопасный тип времени компиляции.
Просто будьте осторожны, не запускайте перечисления, такие как ToList()вызовы, которые нарушат отложенный запрос, и вы можете получить миллион записей обратно из базы данных и отфильтровать их на своем сервере приложений.
Не знаю, правильный ли это способ, но я пробовал, и у меня это работает.
Одна из причин, по которой я хотел бы использовать представления, заключается в том, что SQL, сгенерированный EF, не всегда `` хороший '' - у нас есть некоторые иерархии наследования в нашей модели (мы узнали о подводных камнях слишком поздно ...), и использование представлений позволяет нам чтобы вручную создать SQL. Просто контрапункт относительно того, почему вид был предпочтительнее
Карл
2
Другой причиной не делать этого может быть использование рекурсивных общих табличных выражений, которые недоступны в LINQ. Но в остальном это хороший совет для более простых сценариев.
Том Пажурек
1
Использование свойства вместо представления - не вариант, если вы хотите использовать преимущества индексированного представления.
Rudey
«вы не ограничены только использованием операторов select». Что вы под этим подразумеваете? Все, что вы можете делать с LINQ, можно сделать с помощью операторов SELECT, чего нельзя сказать об обратном.
Rudey
3
Я знаю, что это старый вопрос, и здесь есть много ответов, но я вынужден был задать проблему, когда использую этот ответ, и при использовании команды update-database в консоли диспетчера пакетов возникла ошибка:
В базе данных уже есть объект с именем "...".
и я использую эти шаги для решения этой проблемы:
запустите эту команду в консоли диспетчера пакетов: Добавить начальную миграцию
В папке Migrations вы можете найти файл ..._ intial.cs, открыть его и прокомментировать или удалить любую команду, связанную с вашим классом, который вы хотите сопоставить.
теперь вы обычно можете использовать команду update-database для любых других изменений ваших моделей
Благодарность! Это действительно помогло! В качестве дополнения, вместо простого удаления кода, созданного с помощью EF Migrations, вы можете добавить его туда migrationBuilder.Sql("CREATE OR REPLACE VIEW ...); Чтобы коллеги также могли использовать его для обновления своей базы данных.
Ответы:
Если, как и я, вас интересует только сопоставление сущностей, поступающих из другой базы данных (в моем случае - erp), чтобы связать их с сущностями, специфичными для вашего приложения, то вы можете использовать представления, как вы используете таблицу (сопоставьте представление в так же!). Очевидно, что если вы попытаетесь обновить эти объекты, вы получите исключение, если представление не обновляется. Процедура такая же, как и в случае обычных (основанных на таблице) сущностей:
Используйте файл FooViewConfiguration, чтобы установить другое имя для представления (используя ToTable ("Foo"); в конструкторе) или установить определенные свойства
public class FooViewConfiguration : EntityTypeConfiguration<FooView> { public FooViewConfiguration() { this.HasKey(t => t.Id); this.ToTable("myView"); } }
Добавьте файл FooViewConfiguration в modelBuilder, например, над методом OnModelCreating контекста:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new FooViewConfiguration ()); }
источник
[Table("myView")]
это, возможно, проще, чем созданиеEntityTypeConfiguration
.Это может быть обновление, но для использования представлений с кодом EF сначала просто добавьте [Table ("NameOfView")] в начало класса, и все должно работать правильно, без необходимости проходить через все обручи, через которые проходят все остальные. Также вам нужно будет указать один из столбцов как [ключевой] столбец. Вот мой пример кода ниже для его реализации.
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace SomeProject.Data { [Table("SomeView")] public class SomeView { [Key] public int NameID { get; set; } public string Name { get; set; } } }
А вот как выглядит контекст
using System.Data.Entity; namespace SomeProject.Data { public class DatabaseContext : DbContext { public DbSet<SomeView> SomeViews { get; set; } } }
источник
Если все, что вам нужно, это набор ненормализованных объектов, вы можете просто создать
IQueryable<TDenormolized>
в своемDbContext
классе общедоступное свойство только для получения .В этом случае
get
вы возвращаете результат Linq для проецирования ненормализованных значений в ваши ненормализованные объекты. Это может быть лучше, чем писать представление БД, потому что вы программируете, вы не ограничены только использованиемselect
операторов. Также это безопасный тип времени компиляции.Просто будьте осторожны, не запускайте перечисления, такие как
ToList()
вызовы, которые нарушат отложенный запрос, и вы можете получить миллион записей обратно из базы данных и отфильтровать их на своем сервере приложений.Не знаю, правильный ли это способ, но я пробовал, и у меня это работает.
источник
Я знаю, что это старый вопрос, и здесь есть много ответов, но я вынужден был задать проблему, когда использую этот ответ, и при использовании команды update-database в консоли диспетчера пакетов возникла ошибка:
и я использую эти шаги для решения этой проблемы:
Надеюсь, это поможет.
источник
migrationBuilder.Sql("CREATE OR REPLACE VIEW ...
); Чтобы коллеги также могли использовать его для обновления своей базы данных.