Błędy podczas łączenia z bazą danych. DSP16 – część 9

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

 

Leave a Comment

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *