jak używać widoków w kodzie pierwszej encji [zamknięte]

87

Jak mogę najpierw użyć widoku bazy danych w kodzie struktury jednostki,

Sagar
źródło
2
Żadna z poniższych odpowiedzi nie wyjaśnia, jak utworzyć widok przy użyciu migracji EF. Zobacz tę odpowiedź na podobne pytanie.
Rudey
Oto wątek z dokładnie tym samym pytaniem. - stackoverflow.com/questions/13593845/…
Div Tiwari
Wypróbuj moje rozwiązanie . Zapobiega generowaniu migracji dla tabel oznaczonych jako widoki
kogoia

Odpowiedzi:

95

Jeśli tak jak ja interesuje Cię tylko mapowanie encji pochodzącej z innej bazy danych (w moim przypadku ERP), aby powiązać je z encjami specyficznymi dla Twojej aplikacji, możesz korzystać z widoków tak, jak korzystasz z tabeli (mapuj widok w w ten sam sposób!). Oczywiście, jeśli spróbujesz zaktualizować te encje, otrzymasz wyjątek, jeśli widoku nie można zaktualizować. Procedura jest taka sama jak w przypadku normalnych (opartych na tabeli) podmiotów:

  1. Utwórz klasę POCO dla widoku; na przykład FooView
  2. Dodaj właściwość DbSet do klasy DbContext
  3. Użyj pliku FooViewConfiguration, aby ustawić inną nazwę widoku (za pomocą ToTable („Foo”); w konstruktorze) lub ustawić określone właściwości

    public class FooViewConfiguration : EntityTypeConfiguration<FooView>      
    {
        public FooViewConfiguration()
        {
            this.HasKey(t => t.Id);
            this.ToTable("myView");
        }
    }
    
  4. Dodaj plik FooViewConfiguration do modelBuilder, na przykład zastępując metodę OnModelCreating metody Context:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new FooViewConfiguration ());
    }
    
Daniele Armanasco
źródło
64
+1 za nie zakładanie, że „Code First” == automatyczne generowanie bazy danych
onetwopunch
3
@DaveJellison, czy zechciałbyś to rozwinąć lub podać link do dodawania widoku w ramach IDatabaseInitializer
Ralph Shillington
18
Czy to tylko ja, czy wszyscy otrzymują pustą tabelę utworzoną przez migrację? Czy jest sposób, aby tego uniknąć?
Kremena Lalova
4
Tylko upewniając się tutaj, czy to rozwiązanie wymagało od nas wcześniejszego zewnętrznego utworzenia widoku w bazie danych SQL? Czy można zdefiniować widok w kodzie i zapełnić go w bazie danych za pomocą polecenia Add-Migration / Update-Database?
frostshoxx
6
Kilka rzeczy. 1. W tej odpowiedzi nie ma wzmianki o konieczności ręcznego utworzenia widoku za pomocą SQL, można to zrobić za pomocą migracji. 2. Nie musisz konfigurować nazwy widoku, jeśli nazwa klasy jest zgodna z nazwą widoku. 3. Możesz używać adnotacji danych w następujący sposób: [Table("myView")]jest to prawdopodobnie prostsze niż tworzenie pliku EntityTypeConfiguration.
Rudey
23

Może to być aktualizacja, ale aby użyć widoków z kodem EF, najpierw dodaj [Table ("NameOfView")] na początku klasy i wszystko powinno działać poprawnie bez konieczności przechodzenia przez wszystkie obręcze, przez które przechodzą wszyscy inni. Będziesz także musiał zgłosić jedną z kolumn jako kolumnę [klucz]. Oto mój przykładowy kod poniżej, aby go zaimplementować.

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; }
    }
}

A oto jak wygląda kontekst

using System.Data.Entity;

namespace SomeProject.Data
{
    public class DatabaseContext : DbContext
    {
        public DbSet<SomeView> SomeViews { get; set; }
    }
}
Al Katawazi
źródło
2
Jest to to samo, co zaakceptowana odpowiedź, z tą różnicą, że używa DataAnnotations, podczas gdy zaakceptowana odpowiedź używa interfejsu API EF Fluid.
Rudey
4
Właściwie nie, nie jest. Bez powodzenia spróbowałem zaakceptowanej odpowiedzi i nie wyszło mi to dobrze. Ale potem używam migracji, więc może to mieć wpływ na rzeczy. Okazało się, że najpierw muszę wykonać migracje, a NASTĘPNIE dodać moją klasę widoku, ponieważ już istniała w bazie danych. Zrobilibyśmy to dokładnie w ten sam sposób, gdybyśmy mieli już istniejące tabele w bazie danych. Ponieważ widok jest „wirtualną tabelą”, składnia tabeli w Entity Framework nadal działa.
Charles Owen,
11

Jeśli wszystko, czego chcesz, to zbiór zdenormalizowanych obiektów, możesz po prostu utworzyć publiczną IQueryable<TDenormolized>właściwość tylko do pobierania w swojej DbContextklasie.

W getzwracasz wynik Linq, aby rzutować zdenormalizowane wartości na zdenormalizowane obiekty. To może być lepsze niż pisanie DB View, ponieważ programujesz, nie jesteś ograniczony tylko do używania selectinstrukcji. Jest również bezpieczny w czasie kompilacji.

Po prostu uważaj, aby nie wywoływać wyliczeń, takich jak ToList()wywołania, które spowodują przerwanie odroczonego zapytania i możesz skończyć z odzyskaniem miliona rekordów z bazy danych i przefiltrowaniem ich na serwerze aplikacji.

Nie wiem, czy to właściwy sposób, ale próbowałem i to działa.

oldhouseye
źródło
6
Jednym z powodów, dla których chciałbym używać widoków, jest to, że kod SQL generowany przez EF nie zawsze jest `` ładny '' - w naszym modelu mamy pewne hierarchie dziedziczenia (o pułapkach dowiedzieliśmy się zbyt późno ...), a użycie widoków pozwala nam aby ręcznie utworzyć SQL. Tylko kontrapunkt, dlaczego widok byłby lepszy
Carl
2
Innym powodem, aby tego nie robić, może być użycie rekurencyjnych wspólnych wyrażeń tabelowych, które nie są dostępne w LINQ. Ale poza tym jest to dobra rada dla prostszych scenariuszy.
Tom Pažourek
1
Używanie właściwości zamiast widoku nie jest opcją, jeśli chcesz skorzystać z zalet widoku indeksowanego .
Rudey
„nie ogranicza Cię używanie wyłącznie instrukcji select”. Co przez to rozumiesz? Wszystko, co możesz zrobić z LINQ, można zrobić za pomocą instrukcji SELECT, tego samego nie można powiedzieć na odwrót.
Rudey
3

Wiem, że to stare pytanie i jest tu wiele odpowiedzi, ale wymusiłem problem, gdy używam tej odpowiedzi i wystąpił błąd, gdy używam polecenia update-database w konsoli menedżera pakietów:

W bazie danych istnieje już obiekt o nazwie „...”.

i wykonuję następujące kroki, aby rozwiązać ten problem:

  1. uruchom to polecenie w konsoli Menedżera pakietów: Początek migracji do dodania
  2. W folderze Migrations możesz znaleźć plik ..._ intial.cs, otworzyć go i skomentować lub usunąć dowolne polecenie związane z klasą, którą chcesz zmapować
  3. teraz możesz normalnie użyć polecenia update-database do wszelkich innych zmian w swoich modelach

mam nadzieję, że to pomoże.

Sepehr Estaki
źródło
1
Dzięki! To naprawdę pomogło! Dodatkowo, zamiast po prostu usuwać kod wygenerowany za pomocą migracji EF, możesz zamiast tego dodać migrationBuilder.Sql("CREATE OR REPLACE VIEW ...); Aby współpracownicy mogli również użyć go do aktualizacji swojej bazy danych.
Rich_Rich