как использовать представления в структуре первой сущности кода [закрыто]

87

Как я могу сначала использовать представление базы данных в коде структуры сущности,

Сагар
источник
2
Ни один из ответов ниже не объясняет, как создать представление с помощью миграции EF. См. Этот ответ на аналогичный вопрос.
Rudey
Вот ветка с точно таким же вопросом. - stackoverflow.com/questions/13593845/…
Div Tiwari
Попробуйте мое решение . Это предотвращает создание миграции для таблиц, помеченных как представления
kogoia

Ответы:

95

Если, как и я, вас интересует только сопоставление сущностей, поступающих из другой базы данных (в моем случае - erp), чтобы связать их с сущностями, специфичными для вашего приложения, то вы можете использовать представления, как вы используете таблицу (сопоставьте представление в так же!). Очевидно, что если вы попытаетесь обновить эти объекты, вы получите исключение, если представление не обновляется. Процедура такая же, как и в случае обычных (основанных на таблице) сущностей:

  1. Создайте класс POCO для представления; например FooView
  2. Добавьте свойство DbSet в класс DbContext
  3. Используйте файл FooViewConfiguration, чтобы установить другое имя для представления (используя ToTable ("Foo"); в конструкторе) или установить определенные свойства

    public class FooViewConfiguration : EntityTypeConfiguration<FooView>      
    {
        public FooViewConfiguration()
        {
            this.HasKey(t => t.Id);
            this.ToTable("myView");
        }
    }
    
  4. Добавьте файл FooViewConfiguration в modelBuilder, например, над методом OnModelCreating контекста:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new FooViewConfiguration ());
    }
    
Даниэле Арманаско
источник
64
+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;

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; }
    }
}
Аль Катавази
источник
2
Это то же самое, что и принятый ответ, за исключением того, что в нем используются DataAnnotations, а в принятом ответе используется EF Fluid API.
Rudey
4
На самом деле нет. Я безуспешно пытался ответить на принятый ответ, и у меня это не сработало. Но тогда я использую миграции, так что это могло повлиять на вещи. Я обнаружил, что мне нужно сначала выполнить миграцию, ЗАТЕМ добавить мой класс представления, поскольку он уже существует в базе данных. Мы бы поступили точно так же, если бы у нас уже были существующие таблицы в базе данных. Поскольку представление представляет собой «виртуальную таблицу», синтаксис таблицы в Entity Framework по-прежнему работает.
Чарльз Оуэн
11

Если все, что вам нужно, это набор ненормализованных объектов, вы можете просто создать IQueryable<TDenormolized>в своем DbContextклассе общедоступное свойство только для получения .

В этом случае getвы возвращаете результат Linq для проецирования ненормализованных значений в ваши ненормализованные объекты. Это может быть лучше, чем писать представление БД, потому что вы программируете, вы не ограничены только использованием selectоператоров. Также это безопасный тип времени компиляции.

Просто будьте осторожны, не запускайте перечисления, такие как ToList()вызовы, которые нарушат отложенный запрос, и вы можете получить миллион записей обратно из базы данных и отфильтровать их на своем сервере приложений.

Не знаю, правильный ли это способ, но я пробовал, и у меня это работает.

Oldhouseye
источник
6
Одна из причин, по которой я хотел бы использовать представления, заключается в том, что SQL, сгенерированный EF, не всегда `` хороший '' - у нас есть некоторые иерархии наследования в нашей модели (мы узнали о подводных камнях слишком поздно ...), и использование представлений позволяет нам чтобы вручную создать SQL. Просто контрапункт относительно того, почему вид был предпочтительнее
Карл
2
Другой причиной не делать этого может быть использование рекурсивных общих табличных выражений, которые недоступны в LINQ. Но в остальном это хороший совет для более простых сценариев.
Том Пажурек
1
Использование свойства вместо представления - не вариант, если вы хотите использовать преимущества индексированного представления.
Rudey
«вы не ограничены только использованием операторов select». Что вы под этим подразумеваете? Все, что вы можете делать с LINQ, можно сделать с помощью операторов SELECT, чего нельзя сказать об обратном.
Rudey
3

Я знаю, что это старый вопрос, и здесь есть много ответов, но я вынужден был задать проблему, когда использую этот ответ, и при использовании команды update-database в консоли диспетчера пакетов возникла ошибка:

В базе данных уже есть объект с именем "...".

и я использую эти шаги для решения этой проблемы:

  1. запустите эту команду в консоли диспетчера пакетов: Добавить начальную миграцию
  2. В папке Migrations вы можете найти файл ..._ intial.cs, открыть его и прокомментировать или удалить любую команду, связанную с вашим классом, который вы хотите сопоставить.
  3. теперь вы обычно можете использовать команду update-database для любых других изменений ваших моделей

Надеюсь, это поможет.

Sepehr Estaki
источник
1
Благодарность! Это действительно помогло! В качестве дополнения, вместо простого удаления кода, созданного с помощью EF Migrations, вы можете добавить его туда migrationBuilder.Sql("CREATE OR REPLACE VIEW ...); Чтобы коллеги также могли использовать его для обновления своей базы данных.
Rich_Rich