„Niepowodzenie kompilacji” na Database First Scaffold-DbContext

85

Próbuję wygenerować klasy z bazy danych (pierwsze podejście do bazy danych EntityFramework).

Dla wygody chodzę mniej więcej zgodnie z tym samouczkiem: https://docs.efproject.net/en/latest/platforms/full-dotnet/existing-db.html

Jestem w momencie, w którym uruchamiam odpowiednik tego wiersza kodu w konsoli Menedżera pakietów programu Visual Studio:

Scaffold-DbContext "Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -Verbose

Ten wiersz kodu generuje błąd (przy włączonym trybie -Verbose):

Using startup project 'EFSandbox'.
Using project 'EntityFrameworkCore'
Build started...
Build failed.

Nie widzę innych opcji, które dają jakiekolwiek znaczące wyniki, i nie widzę dokumentacji dotyczącej tego konkretnego błędu. Jeśli to w ogóle pomaga, ten projekt nie ma obecnie pliku project.json. Wszystko jest w pliku .csproj, którego nie edytowałem ręcznie.

LightToTheEnd
źródło
6
Czy otrzymujesz jakieś błędy / ostrzeżenia podczas ponownej kompilacji całego rozwiązania?
Ignas
@Ignas Zrobiłem to i tak, otrzymałem błędy zależności, które nie istniały przed ponowną kompilacją, a które po prostu nie powinny istnieć. Zamiast próbować z tym walczyć, zmieniam rozwiązanie. Ale teraz mam nowy problem. Domyślam się, że po chwili powinienem zadać nowe pytanie (jeśli to jest podobne), zamiast edytować to.
LightToTheEnd
Pomyśl, że Twoim problemem jest to, że musisz mieć plik project.json, aby zadeklarować narzędzia EFC. Spróbuj przepisać we właściwym typie projektu, co może wygenerować plik JSON.
Webezine
1
Dla mnie to, co sprawiło, że działało, to upewnienie się, że całe rozwiązanie (nie tylko projekt) zostało pomyślnie zbudowane przed wydaniem polecenia scaffold.
manish gupta
Chciałem pokrótce zaktualizować to pytanie, ponieważ zwróciło ono dużo uwagi - dotyczyło to znacznie starszej wersji EF Core niż ta, która jest obecnie dostępna, a po kilku innych problemach rozwiązaniem, z którym skończyliśmy, był EF6, dopóki Core nie miał więcej czasu na osiedlenie się. Nawet EF6 stwarzał problemy, ale ustawiliśmy go znacznie bardziej niezawodnie.
LightToTheEnd

Odpowiedzi:

158

Dwie najważniejsze wskazówki:

[1] - Upewnij się, że projekt jest całkowicie kompilowany, zanim uruchomisz nowe polecenie szkieletu.

Inaczej...

  • Zaczniesz pisać linię kodu.
  • Zrozumiesz, że w modelu brakuje wymaganej kolumny DB.
  • Pójdziesz spróbować go zbudować.
  • Dwadzieścia minut później zdasz sobie sprawę, że przyczyną niepowodzenia kompilacji (i polecenia tworzenia szkieletu) jest to, że masz dosłownie napisaną w połowie linię kodu. Ups!

[2] - Sprawdź w kontroli źródła lub zrób kopię:

  • Pozwala łatwo zweryfikować, co się zmieniło.
  • W razie potrzeby umożliwia wycofanie.

Jeśli masz pecha lub popełnisz błąd, możesz mieć bardzo irytujące problemy z jajkiem i kury.


Inne problemy:

Jeśli masz wiele bibliotek DLL, upewnij się, że nie generujesz do niewłaściwego projektu . Komunikat „Niepowodzenie kompilacji” może wystąpić z wielu powodów, ale najgłupszy byłby, gdybyś nie miał zainstalowanego EFCore w projekcie, w którym tworzysz rusztowanie.

W konsoli menedżera pakietów znajduje się Default projectlista rozwijana i prawdopodobnie tam trafiły Twoje nowe pliki, jeśli brakuje oczekiwanej zmiany.

Lepszym rozwiązaniem niż pamiętanie o ustawieniu listy rozwijanej jest dodanie -Projectprzełącznika do polecenia dotyczącego rusztowania.

Oto pełne polecenie, którego używam:

W przypadku EF Core 2

Scaffold-DbContext -Connection "Server = (lokalny); Database = DefenderRRCart; Integrated Security = True; Trusted_Connection = True;" -Provider Microsoft.EntityFrameworkCore.SqlServer -OutputDir RRStoreContext.Models -context RRStoreContext -Project RR.DataAccess -force

W przypadku EF Core 3

dotnet ef dbcontext scaffold "Server = tcp: XXXXX.database.windows.net, 1433; Initial Catalog = DATABASE_NAME; Persist Security Info = False; User ID = USERNAME; Password = PASSWORD; MultipleActiveResultSets = False; Encrypt = True; TrustServerCertificate = False ; Limit czasu połączenia = 30; " Microsoft.EntityFrameworkCore.SqlServer -o DB.Models --context-dir DB.Contexts --context RRDBContext --project RR.EF.csproj --force --use-database-names

Uwaga: -force nadpisze pliki, ale nie usunie tych, które już nie istnieją. Jeśli usuniesz tabele ze swojej bazy danych, musisz samodzielnie usunąć stare pliki encji (po prostu posortuj w Eksploratorze według daty i usuń stare).


Pełne odniesienie do rusztowania:

EF Core 2:

https://docs.efproject.net/en/latest/miscellaneous/cli/powershell.html#scaffold-dbcontext (this

EF Core 3:

https://docs.microsoft.com/en-us/ef/core/miscellaneous/cli/dotnet

Simon_Weaver
źródło
upewnij się również, że pliki Project.JSON nie zawierają komentarzy
Simon_Weaver
I tak, możesz zbudować szkielet w projekcie `` biblioteki klas '', jeśli wolisz logikę dostępu do danych w oddzielnym pliku, ale projekt główny musi być projektem rdzenia aspnet
Simon_Weaver
Wskazówka: upewnij się, że uruchamiasz z konsoli menedżera pakietów. Nie działa dla mnie, uruchamiając z wiersza polecenia programu Visual Studio
Simon_Weaver
1
co zrobisz, jeśli na przykład usunąłeś plik encji? Rusztowanie nie będzie działać, ponieważ brakuje tego pliku, ale nie będzie ono działać, ponieważ nie jest kompilowane. Dość irytujące.
sofsntp
6
Irytujące wydaje się, że musisz być w stanie zbudować całe rozwiązanie. Miałem błędy w innych projektach, ale projekt rusztowania był w porządku. Rozwiązaniem było wybranie innych projektów i „wyładowanie” ich. Następnie rusztuj i przeładuj.
Sam,
11

Wiem, że to stare, ale spędziłem trochę czasu próbując to rozgryźć dzisiaj, więc mam nadzieję, że to komuś pomoże.

Mam projekt .Net Core, ale chcę szkieletować moje pliki do biblioteki klas .Net Standard. DbContext-Scaffoldw konsoli menedżera pakietów nie działało dla mnie, ale dotnet ef dbcontext scaffoldw zwykłym wierszu poleceń tak.

Musiałem zainstalować te pakiety w mojej bibliotece klas:

  • Microsoft.EntityFrameworkCore.SqlServer
  • Microsoft.EntityFrameworkCore.Design
  • Microsoft.EntityFrameworkCore.Tools

Musiałem mieć projekt .Net Core ustawiony jako projekt startowy w moim rozwiązaniu i ten projekt musiał mieć odniesienie do mojej biblioteki klas . Myślę, że ta ostatnia część jest tym, czego mi brakowało, przez co tak długo drapałem się po głowie.

W końcu wszedłem do biblioteki klas z wiersza poleceń i uruchomiłem to:

dotnet ef dbcontext scaffold "<connection string>" Microsoft.EntityFrameworkCore.SqlServer -o <output folder> -s <relative path to my startup project>
melicent
źródło
11

Ręczne budowanie projektu przez naciśnięcie Ctrl + Shift + B pomogło mi zobaczyć błędy, które powodowały niepowodzenie kompilacji.

Mxaza
źródło
Tak, kompilacja rozwiązania też mi pomogła.
Piero Alberto
Zgodnie z przyjętą odpowiedzią już przed laty. „Przed uruchomieniem nowego polecenia szkieletu upewnij się, że projekt został całkowicie skompilowany”.
Gert Arnold
5

Nadal miałem ten problem, nawet gdy upewniłem się, że mój projekt (z zainstalowanym EF Core) został poprawnie zbudowany. Nadal nie udało się z komunikatem „Budowa nie powiodła się”. wiadomość, która jest widoczna podczas używania -Verbsoseflagi.

Musiałem to zrobić w moim przypadku:

  • Utwórz jednorazowe rozwiązanie aplikacji sieci Web ASP.NET Core
  • Dodaj pakiet EF Core NuGet do rozwiązania
  • Dodaj pakiet NuGet dostawcy EF Core Sql Server (ponieważ używam SqlServer)
  • Dodaj pakiet NuGet EF Core Tools
  • Przełącz się -Projectw poleceniu konsoli Menedżera pakietów, aby wskazać mój nowo utworzony (i udostępniony EF Core) projekt. Ostatni krok był po prostu na miarę, ponieważ w moim jednorazowym rozwiązaniu był tylko jeden projekt.

Wygląda na to, że cały ten proces wymaga gdzieś w rozwiązaniu projektu ASP.NET core (lub po prostu projektu .NET Core, który nie jest biblioteką klas), prawdopodobnie również ustawionego jako projekt startowy rozwiązania.

bcr
źródło
2
To prawdopodobnie jeden z bardziej przydatnych wpisów na tej stronie. Flaga -verbose powinna przesuwać się we właściwym kierunku, ponieważ obejmuje wiele rzeczy, które mogą się nie udać na rusztowaniu.
Regianni
5

Upewnij się, że projekt nie jest uruchomiony, z jakiegoś powodu to polecenie nie działa, gdy mój interfejs API działa w tle.

Josh Siegl
źródło
4

Korzystając z VS2017 Preview 3, .NET Core 2 (PREVIEW) miałem różnego rodzaju problemy, ale ostatecznie zastosowałem podejście sugerowane powyżej i stworzyłem zupełnie nowe rozwiązanie.

  1. Utworzono nowe rozwiązanie .NET Core
  2. Edytowany plik projektu i zmieniony z 1.0 na 2.0: <TargetFramework>netcoreapp2.0</TargetFramework>
  3. Rozwiązanie zamknięte / ponownie otwarte

Następnie dodano Entity Framework:

  1. W konsoli PackageManager:
    • Pakiet instalacyjny Microsoft.EntityFrameworkCore.SqlServer -Version 2.0.0-preview2-final
    • Pakiet instalacyjny Microsoft.EntityFrameworkCore.Tools -Version 2.0.0-preview2-final
    • Zainstaluj pakiet Microsoft.EntityFrameworkCore.Design -Version 2.0.0-preview2-final
  2. Edytowany plik projektu i dodano: <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.Dotnet" Version="2.0.0-preview2-final" />

Następnie;

  1. Otwarto wiersz polecenia programu PowerShell i zmieniono katalog na folder projektu Scaffold
  2. Ran: dotnet ef dbcontext scaffold "Server = DESKTOP-MB70B7U; Database = ForexForme; Trusted_Connection = True" Microsoft.EntityFrameworkCore.SqlServer -o Models
    • Gdzie wstawiasz własne parametry połączenia!
    • Modele to nazwa mojego katalogu, w którym umieszczam wszystkie moje zajęcia
James Joyce
źródło
4

Zbuduj kompletne rozwiązanie i zobacz, gdzie zawodzi. Niektóre projekty NuGet zostały ukryte w folderze, który nie został skompilowany. Dopiero podczas przebudowy rozwiązania dowiedziałem się, na czym polega problem. Wszystko musi zostać zbudowane, inaczej rusztowanie zawiedzie.

Guido Neele
źródło
4

Jeśli korzystasz z wielu projektów w rozwiązaniu, sprawdź domyślny projekt w menedżerze pakietów.

Muhammet Bozkan
źródło
3

Dla mnie problem polegał na tym, że próbowałem ustawić go w nowym pustym projekcie konsoli wewnątrz rozwiązania, które nie miało plików, więc rusztowanie próbowało użyć tego projektu jako projektu startowego i nie mogło go znaleźć Main. Naprawiłem to, dodając nowy plik z pustym plikiem main

Austin_Anderson
źródło
3

Dzięki temu przebudowanie rozwiązania projektowego rozwiązało ten problem. Niektóre kluczowe zastrzeżenia dla mnie osobiście to:

  1. Uruchomienie dotnet buildnie wystarczyło (zakładałem, że tak)!
  2. W menu programu Visual Studio, Kompiluj> Kompiluj rozwiązanie (Ctrl + Shift + B)
    • dotnet buildWydaje mi się, że po prostu próbowałem uruchomić polecenie w projekcie podrzędnym (myProject.data)
    • Kluczem była przebudowa rozwiązania projektu nadrzędnego (myProject)

Mam nadzieję, że pomoże to komuś, kto był równie zdezorientowany!

Joel Balmer
źródło
3

Rozwiązałem to, klikając prawym przyciskiem myszy projekty i „Zwolnij projekt”, pozwalając tylko projektowi EF i uruchamiać polecenia

user1499903
źródło
2

Jeśli struktura encji zwraca build failed, najprawdopodobniej wystąpił jakiś błąd w którymkolwiek ze swoich projektów.

Nawet jeśli projekt, na którym uruchamiasz polecenie, jest czysty i wolny od błędów, inne projekty w tym rozwiązaniu mogą spowodować build failedodpowiedź.

Rozwiązanie

  • Przebuduj całe rozwiązanie. Najprawdopodobniej znajdziesz ten błąd w procesie odbudowy rozwiązania.
  • Upewnij się, że projekt, w którym chcesz uruchomić polecenie, jest wybrany w Default projectrozwijanym menuPackage Manager Console
  • Ponownie uruchom polecenie.
Inam Ul Huq
źródło
1

Dla mnie mój projekt został zbudowany w programie Visual Studio, ale musiałem określić wersję dla „Microsoft.AspNetCore.App” podczas uruchamiania Scaffold-DbContext.

Więc zamiast:

<PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <RuntimeFrameworkVersion>2.1.6</RuntimeFrameworkVersion>
</PropertyGroup>
<ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App"/>
</ItemGroup>

Musiałem mieć:

<PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.6" />
</ItemGroup>
Kpt.Ohlund
źródło
1

Upewnij się, że Twoja kompilacja działa poprawnie.
Uruchom polecenie scaffold z konsoli pakietów, twoje polecenie powinno działać:

Scaffold-DbContext 'Data Source=TEST-XY010;Initial Catalog=TESTDB;Trusted_Connection=True' Microsoft.EntityFrameworkCore.SqlServer -Context HOPWAContext -OutputDir TESTModel -Force
Shakil
źródło
1

Rozwiązałem ten problem, zatrzymując serwer, a następnie uruchamiając go ponownie.

tblev
źródło
0

To przestało dzisiaj dla mnie działać. Próbowałem więc uruchomić polecenie dotnet scaffold z wiersza polecenia i zadziałało za pierwszym razem. Nie pytaj mnie !!

Regianni
źródło
Zerwał się ponownie, zanim odkryłem flagę --verbose, która dostarczyła ślad stosu, który pozwolił mi zidentyfikować problem. Prawdopodobnie pomogłoby, gdyby błąd był wyświetlany niezależnie od tej flagi.
Regianni
-1

Upewnij się, że masz wszystkie pakiety i naciśnij ctrl + shift + b, aby skompilować rozwiązanie. Na mnie to działa.

Ivan Cardozo
źródło
Zgodnie z przyjętą odpowiedzią już przed laty. „Przed uruchomieniem nowego polecenia szkieletu upewnij się, że projekt został całkowicie skompilowany”.
Gert Arnold
-1
  1. Upewnij się, że projekt nie jest uruchomiony
  2. Upewnij się, że Twój projekt się kompiluje

To zadziałało dla mnie.

José Maurício
źródło