Drugi raz w tym projekcie czułem się w beznadziejnej sytuacji kiedy próbowałem coś zaimplementować, a nic nie chciało działać. Szukanie błędów jest dla mnie fajną sprawą dopóki nie uważam, że zrobiłem wszystko jak należy a coś dalej nie działa. Wtedy nachodzi mnie konsternacja i zrezygnowanie. W takich momentach najlepiej sprawdza się w moim przypadku przerwa na co najmniej pół godziny.
Zaczęło się niewinnie. Odpaliłem VS, chciałem skompliować projekt i wyskoczył mi błąd:
An error occurred attempting to determine the process id of the DNXprocess hosting your application.
Niestety pierwsze wyniki w googlu mi nie pomogły (StackOverFlow). Gdzieś znalazłem wskazówkę, żeby odpalić projekt przy użyciu opcji „Start project without debbuging” (Ctrl+F5). I dzięki temu zabiegowi otrzymałem bardziej znaczący błąd:
The configuration section ‚entityFramework’ cannot be read because it is missing a section declaration
Znalazłem na Stacku informację, że to może być wina web.configa. Na początku mój web.config wyglądał tak:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
</handlers>
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/>
</system.webServer>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
</configuration>
Po zastosowaniu się do propozycji naprawy tego błędu ze Stacka dodałem do web.configa linijkę:
<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
</configuration>
Po prawdzie projekt kompilował się już, ale to rozwiązanie jakoś mi się nie podobało. Zrobiłem małe dochodzenie: odpaliłem nowy projekt -> zrobiłem na szybko EF First Code Approach i odkryłem, że w nowym projekcie nie ma całej sekcji entityFramework. Wyrzuciłem więc tą sekcję i projekt się dalej kompilował i działał. Więc idąc tym tropem mój nowy web.config prezentował się tak:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
</handlers>
<httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/>
</system.webServer>
</configuration>
Następnie stwierdziłem, że sprawdzę czy EF zaciąga dane z bazy danych. Dodałem nowy rekord do bazy danych i spróbowałem skompilować. Dostałem po oczach nowym błędem:
Additional information: No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services.
Błąd pojawił się na linijce:
return Context.Set<TEntity>().ToList();
Czyli w miejscu gdzie strikte odwoływałem się do bazy danych. Rozwiązaniem może być na przykład stworzenie odpowiedniego konstruktora, bądź nadpisanie metody OnConfiguring.
public class ApplicationContext : DbContext
{
public DbSet<Player> Players { get; set; }
public DbSet<Tournament> Tournaments { get; set; }
public DbSet<Venue> Venues { get; set; }
public DbSet<Achievement> Achievements { get; set; }
public DbSet<Result> Results { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer("Data Source=TOMASZ\\SQLEXPRESS;Initial Catalog=PokerWebsite;Integrated Security=True");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
modelBuilder.Entity(entity.Name).ToTable(entity.Name + "s");
}
modelBuilder.Entity<Result>().HasKey(x => new { x.PlayerID, x.TournamentID });
modelBuilder.Entity<PlayerAchievement>().HasKey(x => new { x.PlayerID, x.AchievementID });
}
}