Zaawansowane scenariusze programu Entity Framework dla aplikacji internetowej MVC (10 z 10)
Autor: Tom Dykstra
Przykładowa aplikacja internetowa Contoso University pokazuje, jak tworzyć aplikacje ASP.NET MVC 4 przy użyciu programu Entity Framework 5 Code First i Visual Studio 2012. Aby uzyskać informacje na temat serii samouczków, zobacz pierwszy samouczek z serii.
Uwaga
Jeśli napotkasz problem, którego nie możesz rozwiązać, pobierz ukończony rozdział i spróbuj odtworzyć problem. Zazwyczaj rozwiązanie problemu można znaleźć, porównując kod z ukończonym kodem. Aby uzyskać informacje o niektórych typowych błędach i sposobach ich rozwiązywania, zobacz Błędy i obejścia.
W poprzednim samouczku zaimplementowano repozytorium i jednostkę wzorców pracy. W tym samouczku omówiono następujące tematy:
- Wykonywanie nieprzetworzonych zapytań SQL.
- Wykonywanie zapytań bez śledzenia.
- Badanie zapytań wysyłanych do bazy danych.
- Praca z klasami serwerów proxy.
- Wyłączanie automatycznego wykrywania zmian.
- Wyłączanie walidacji podczas zapisywania zmian.
- Błędy i obejścia
W większości tych tematów będziesz pracować z utworzonymi stronami. Aby użyć pierwotnego kodu SQL do zbiorczego aktualizowania, należy utworzyć nową stronę, która aktualizuje liczbę środków na wszystkie kursy w bazie danych:
Aby użyć zapytania bez śledzenia, do strony Edycja działu dodasz nową logikę walidacji:
Wykonywanie nieprzetworzonych zapytań SQL
Interfejs API Code First programu Entity Framework zawiera metody, które umożliwiają przekazywanie poleceń SQL bezpośrednio do bazy danych. Do wyboru są następujące opcje:
DbSet.SqlQuery
Użyj metody dla zapytań, które zwracają typy jednostek. Zwrócone obiekty muszą być typu oczekiwanego przezDbSet
obiekt i są one automatycznie śledzone przez kontekst bazy danych, chyba że wyłączysz śledzenie. (Zobacz następującą sekcjęAsNoTracking
dotyczącą metody).Database.SqlQuery
Użyj metody dla zapytań, które zwracają typy, które nie są jednostkami. Zwrócone dane nie są śledzone przez kontekst bazy danych, nawet jeśli używasz tej metody do pobierania typów jednostek.- Użyj polecenia Database.ExecuteSqlCommand dla poleceń innych niż zapytania.
Jedną z zalet korzystania z platformy Entity Framework jest unikanie zbyt ścisłego wiązania kodu z określoną metodą przechowywania danych. Robi to przez wygenerowanie zapytań SQL i poleceń dla Ciebie, co pozwala również uwolnić cię od konieczności samodzielnego pisania ich. Istnieją jednak wyjątkowe scenariusze, w których trzeba uruchamiać określone zapytania SQL utworzone ręcznie, a te metody umożliwiają obsługę takich wyjątków.
Tak jak zawsze w przypadku wykonywania poleceń SQL w aplikacji internetowej, należy podjąć środki ostrożności, aby chronić witrynę przed atakami polegającymi na wstrzyknięciu kodu SQL. Jednym ze sposobów na to jest użycie sparametryzowanych zapytań w celu upewnienia się, że ciągi przesłane przez stronę internetową nie mogą być interpretowane jako polecenia SQL. W tym samouczku użyjesz sparametryzowanych zapytań podczas integrowania danych wejściowych użytkownika z zapytaniem.
Wywoływanie zapytania zwracającego jednostki
Załóżmy, że chcesz, GenericRepository
aby klasa zapewniała dodatkową elastyczność filtrowania i sortowania bez konieczności tworzenia klasy pochodnej z dodatkowymi metodami. Jednym ze sposobów osiągnięcia tego celu jest dodanie metody akceptującej zapytanie SQL. Następnie można określić dowolny rodzaj filtrowania lub sortowania w kontrolerze, na przykład Where
klauzulę, która zależy od sprzężeń lub podzapytania. W tej sekcji zobaczysz, jak zaimplementować taką metodę.
Utwórz metodę GetWithRawSql
, dodając następujący kod do GenericRepository.cs:
public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
W CourseController.cs wywołaj nową metodę z Details
metody , jak pokazano w poniższym przykładzie:
public ActionResult Details(int id)
{
var query = "SELECT * FROM Course WHERE CourseID = @p0";
return View(unitOfWork.CourseRepository.GetWithRawSql(query, id).Single());
}
W takim przypadku można było użyć GetByID
metody , ale używasz GetWithRawSql
metody w celu sprawdzenia, czy GetWithRawSQL
metoda działa.
Uruchom stronę Szczegóły, aby sprawdzić, czy wybrane zapytanie działa (wybierz kartę Kurs , a następnie pozycję Szczegóły dla jednego kursu).
Wywoływanie zapytania zwracającego inne typy obiektów
Wcześniej utworzono siatkę statystyk uczniów dla strony Informacje, która pokazała liczbę uczniów dla każdej daty rejestracji. Kod, który wykonuje to w HomeController.cs używa LINQ:
var data = from student in db.Students
group student by student.EnrollmentDate into dateGroup
select new EnrollmentDateGroup()
{
EnrollmentDate = dateGroup.Key,
StudentCount = dateGroup.Count()
};
Załóżmy, że chcesz napisać kod, który pobiera te dane bezpośrednio w języku SQL, zamiast używać LINQ. Aby to zrobić, należy uruchomić zapytanie zwracające coś innego niż obiekty jednostki, co oznacza, że należy użyć Database.SqlQuery
metody .
W HomeController.cs zastąp instrukcję LINQ w metodzie About
następującym kodem:
var query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount "
+ "FROM Person "
+ "WHERE EnrollmentDate IS NOT NULL "
+ "GROUP BY EnrollmentDate";
var data = db.Database.SqlQuery<EnrollmentDateGroup>(query);
Uruchom stronę Informacje. Wyświetla te same dane, które zostały wcześniej.
Wywoływanie zapytania aktualizacji
Załóżmy, że administratorzy platformy Contoso University chcą mieć możliwość przeprowadzania zbiorczych zmian w bazie danych, takich jak zmiana liczby środków na każdy kurs. Jeśli uczelnia ma dużą liczbę kursów, byłoby nieefektywne pobranie ich wszystkich jako jednostek i zmiana ich indywidualnie. W tej sekcji zaimplementujesz stronę internetową, która umożliwia użytkownikowi określenie współczynnika, za pomocą którego można zmienić liczbę środków na wszystkie kursy, a następnie wprowadzisz zmianę, wykonując instrukcję SQL UPDATE
. Strona internetowa będzie wyglądać podobnie do poniższej ilustracji:
W poprzednim samouczku użyto repozytorium ogólnego do odczytywania i aktualizowania Course
jednostek w kontrolerze Course
. W przypadku tej operacji zbiorczej aktualizacji należy utworzyć nową metodę repozytorium, która nie znajduje się w repozytorium ogólnym. W tym celu utworzysz dedykowaną CourseRepository
klasę, która pochodzi z GenericRepository
klasy .
W folderze DAL utwórz CourseRepository.cs i zastąp istniejący kod następującym kodem:
using System;
using ContosoUniversity.Models;
namespace ContosoUniversity.DAL
{
public class CourseRepository : GenericRepository<Course>
{
public CourseRepository(SchoolContext context)
: base(context)
{
}
public int UpdateCourseCredits(int multiplier)
{
return context.Database.ExecuteSqlCommand("UPDATE Course SET Credits = Credits * {0}", multiplier);
}
}
}
W UnitOfWork.cs zmień Course
typ repozytorium z GenericRepository<Course>
na CourseRepository:
private CourseRepository courseRepository;
public CourseRepository CourseRepository
{
get
{
if (this.courseRepository == null)
{
this.courseRepository = new CourseRepository(context);
}
return courseRepository;
}
}
W CourseController.cs dodaj metodę UpdateCourseCredits
:
public ActionResult UpdateCourseCredits(int? multiplier)
{
if (multiplier != null)
{
ViewBag.RowsAffected = unitOfWork.CourseRepository.UpdateCourseCredits(multiplier.Value);
}
return View();
}
Ta metoda będzie używana zarówno dla metody , jak HttpGet
i HttpPost
. Po uruchomieniu HttpGet
UpdateCourseCredits
metody zmienna multiplier
będzie mieć wartość null, a widok wyświetli puste pole tekstowe i przycisk przesyłania, jak pokazano na poprzedniej ilustracji.
Po kliknięciu przycisku Aktualizuj i uruchomieniu multiplier
HttpPost
metody zostanie wprowadzona wartość w polu tekstowym. Następnie kod wywołuje metodę repozytorium UpdateCourseCredits
, która zwraca liczbę wierszy, których dotyczy problem, i ta wartość jest przechowywana w ViewBag
obiekcie. Gdy widok odbiera liczbę wierszy, których dotyczy problem w ViewBag
obiekcie, wyświetla ten numer zamiast pola tekstowego i przycisk przesyłania, jak pokazano na poniższej ilustracji:
Utwórz widok w folderze Views\Course na stronie Aktualizowanie środków na kurs:
W pliku Views\Course\UpdateCourseCredits.cshtml zastąp kod szablonu następującym kodem:
@model ContosoUniversity.Models.Course
@{
ViewBag.Title = "UpdateCourseCredits";
}
<h2>Update Course Credits</h2>
@if (ViewBag.RowsAffected == null)
{
using (Html.BeginForm())
{
<p>
Enter a number to multiply every course's credits by: @Html.TextBox("multiplier")
</p>
<p>
<input type="submit" value="Update" />
</p>
}
}
@if (ViewBag.RowsAffected != null)
{
<p>
Number of rows updated: @ViewBag.RowsAffected
</p>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Uruchom metodę UpdateCourseCredits
, wybierając kartę Kursy , a następnie dodając ciąg "/UpdateCourseCredits" na końcu adresu URL na pasku adresu przeglądarki (na przykład: http://localhost:50205/Course/UpdateCourseCredits
). Wprowadź liczbę w polu tekstowym:
Kliknij Aktualizuj. Zostanie wyświetlona liczba wierszy, których dotyczy problem:
Kliknij przycisk Wstecz do listy , aby wyświetlić listę kursów z poprawioną liczbą kredytów.
Aby uzyskać więcej informacji na temat nieprzetworzonych zapytań SQL, zobacz Nieprzetworzone zapytania SQL na blogu zespołu platformy Entity Framework.
Zapytania bez śledzenia
Gdy kontekst bazy danych pobiera wiersze bazy danych i tworzy obiekty jednostki, które je reprezentują, domyślnie śledzi, czy jednostki w pamięci są zsynchronizowane z elementami w bazie danych. Dane w pamięci działają jako pamięć podręczna i są używane podczas aktualizowania jednostki. Buforowanie jest często niepotrzebne w aplikacji internetowej, ponieważ wystąpienia kontekstu są zwykle krótkotrwałe (nowy jest tworzony i usuwany dla każdego żądania) oraz kontekst, który odczytuje jednostkę, jest zwykle usuwany przed ponownym użyciu tej jednostki.
Można określić, czy kontekst śledzi obiekty jednostek dla zapytania przy użyciu AsNoTracking
metody . Typowe scenariusze, w których warto to zrobić, obejmują następujące czynności:
- Zapytanie pobiera tak dużą ilość danych, że wyłączenie śledzenia może znacznie zwiększyć wydajność.
- Chcesz dołączyć jednostkę, aby ją zaktualizować, ale wcześniej pobrano tę samą jednostkę w innym celu. Ponieważ jednostka jest już śledzona przez kontekst bazy danych, nie można dołączyć jednostki, którą chcesz zmienić. Jednym ze sposobów, aby temu zapobiec, jest użycie
AsNoTracking
opcji z wcześniejszym zapytaniem.
W tej sekcji zaimplementujesz logikę biznesową, która ilustruje drugą z tych scenariuszy. W szczególności wymusisz regułę biznesową, która mówi, że instruktor nie może być administratorem więcej niż jednego działu.
W DepartmentController.cs dodaj nową metodę, którą można wywołać z Edit
metod i Create
, aby upewnić się, że żaden z dwóch działów nie ma tego samego administratora:
private void ValidateOneAdministratorAssignmentPerInstructor(Department department)
{
if (department.PersonID != null)
{
var duplicateDepartment = db.Departments
.Include("Administrator")
.Where(d => d.PersonID == department.PersonID)
.FirstOrDefault();
if (duplicateDepartment != null && duplicateDepartment.DepartmentID != department.DepartmentID)
{
var errorMessage = String.Format(
"Instructor {0} {1} is already administrator of the {2} department.",
duplicateDepartment.Administrator.FirstMidName,
duplicateDepartment.Administrator.LastName,
duplicateDepartment.Name);
ModelState.AddModelError(string.Empty, errorMessage);
}
}
}
Dodaj kod w try
bloku HttpPost
Edit
metody , aby wywołać tę nową metodę, jeśli nie ma błędów walidacji. Blok try
wygląda teraz jak w poniższym przykładzie:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(
[Bind(Include = "DepartmentID, Name, Budget, StartDate, RowVersion, PersonID")]
Department department)
{
try
{
if (ModelState.IsValid)
{
ValidateOneAdministratorAssignmentPerInstructor(department);
}
if (ModelState.IsValid)
{
db.Entry(department).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}
catch (DbUpdateConcurrencyException ex)
{
var entry = ex.Entries.Single();
var clientValues = (Department)entry.Entity;
Uruchom stronę Edycja działu i spróbuj zmienić administratora działu na instruktora, który jest już administratorem innego działu. Zostanie wyświetlony oczekiwany komunikat o błędzie:
Teraz ponownie uruchom stronę Edycja działu i tym razem zmień kwotę budżetu . Po kliknięciu przycisku Zapisz zobaczysz stronę błędu:
Komunikat o błędzie wyjątku to "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.
" Wystąpił z powodu następującej sekwencji zdarzeń:
- Metoda
Edit
wywołuje metodęValidateOneAdministratorAssignmentPerInstructor
, która pobiera wszystkie działy z Kim Abercrombie jako administrator. To powoduje, że departament angielski jest odczytywany. Ponieważ jest to edytowany dział, nie jest zgłaszany żaden błąd. W wyniku tej operacji odczytu jednostka działu angielskiego, która została odczytowana z bazy danych, jest teraz śledzona przez kontekst bazy danych. - Metoda
Edit
próbuje ustawić flagęModified
w jednostce działu angielskiego utworzonej przez binder modelu MVC, ale kończy się to niepowodzeniem, ponieważ kontekst już śledzi jednostkę dla działu angielskiego.
Jednym z rozwiązań tego problemu jest zachowanie kontekstu przed śledzeniem jednostek działu w pamięci pobranych przez zapytanie sprawdzania poprawności. Nie ma żadnej niekorzystnej sytuacji w tym celu, ponieważ nie będziesz aktualizować tej jednostki ani odczytywać jej ponownie w sposób, który skorzysta z buforowania w pamięci.
W DepartmentController.cs w metodzie ValidateOneAdministratorAssignmentPerInstructor
określ brak śledzenia, jak pokazano poniżej:
var duplicateDepartment = db.Departments
.Include("Administrator")
.Where(d => d.PersonID == department.PersonID)
.AsNoTracking()
.FirstOrDefault();
Powtórz próbę edytowania kwoty budżetu działu. Tym razem operacja zakończy się pomyślnie, a witryna zwróci wartość zgodnie z oczekiwaniami na stronie Indeks działów z wyświetloną poprawioną wartością budżetu.
Badanie zapytań wysyłanych do bazy danych
Czasami warto zobaczyć rzeczywiste zapytania SQL wysyłane do bazy danych. W tym celu możesz zbadać zmienną zapytania w debugerze lub wywołać metodę zapytania ToString
. Aby wypróbować tę metodę, przyjrzysz się prostemu zapytaniu, a następnie przyjrzymy się temu, co się stanie, dodając opcje takie chętne do ładowania, filtrowania i sortowania.
W pliku Controllers/CourseController zastąp metodę Index
następującym kodem:
public ViewResult Index()
{
var courses = unitOfWork.CourseRepository.Get();
return View(courses.ToList());
}
Teraz ustaw punkt przerwania w GenericRepository.cs w return query.ToList();
instrukcjach Get
i return orderBy(query).ToList();
metody . Uruchom projekt w trybie debugowania i wybierz stronę Indeks kursu. Gdy kod osiągnie punkt przerwania, sprawdź zmienną query
. Zostanie wyświetlone zapytanie wysyłane do programu SQL Server. Jest to prosta Select
instrukcja:
{SELECT
[Extent1].[CourseID] AS [CourseID],
[Extent1].[Title] AS [Title],
[Extent1].[Credits] AS [Credits],
[Extent1].[DepartmentID] AS [DepartmentID]
FROM [Course] AS [Extent1]}
Zapytania mogą być zbyt długie, aby wyświetlać je w oknach debugowania w programie Visual Studio. Aby wyświetlić całe zapytanie, możesz skopiować wartość zmiennej i wkleić ją do edytora tekstów:
Teraz dodasz listę rozwijaną do strony Indeks kursu, aby użytkownicy mogli filtrować dla określonego działu. Posortujesz kursy według tytułu i określisz chętne Department
ładowanie dla właściwości nawigacji. W CourseController.cs zastąp metodę Index
następującym kodem:
public ActionResult Index(int? SelectedDepartment)
{
var departments = unitOfWork.DepartmentRepository.Get(
orderBy: q => q.OrderBy(d => d.Name));
ViewBag.SelectedDepartment = new SelectList(departments, "DepartmentID", "Name", SelectedDepartment);
int departmentID = SelectedDepartment.GetValueOrDefault();
return View(unitOfWork.CourseRepository.Get(
filter: d => !SelectedDepartment.HasValue || d.DepartmentID == departmentID,
orderBy: q => q.OrderBy(d => d.CourseID),
includeProperties: "Department"));
}
Metoda odbiera wybraną wartość listy rozwijanej w parametrze SelectedDepartment
. Jeśli nic nie zostanie wybrane, ten parametr będzie mieć wartość null.
SelectList
Kolekcja zawierająca wszystkie działy jest przekazywana do widoku listy rozwijanej. Parametry przekazane do konstruktora SelectList
określają nazwę pola wartości, nazwę pola tekstowego i wybrany element.
Get
W przypadku metody Course
repozytorium kod określa wyrażenie filtru, kolejność sortowania i chętne ładowanie dla Department
właściwości nawigacji. Wyrażenie filtru zawsze zwraca true
wartość, jeśli nic nie jest zaznaczone na liście rozwijanej (czyli SelectedDepartment
ma wartość null).
W pliku Views\Course\Index.cshtml bezpośrednio przed tagiem otwierania table
dodaj następujący kod, aby utworzyć listę rozwijaną i przycisk przesyłania:
@using (Html.BeginForm())
{
<p>Select Department: @Html.DropDownList("SelectedDepartment","All")
<input type="submit" value="Filter" /></p>
}
Po ustawieniu punktów przerwania w GenericRepository
klasie uruchom stronę Indeks kursu. Przejdź przez pierwsze dwa razy, gdy kod osiągnie punkt przerwania, tak aby strona jest wyświetlana w przeglądarce. Wybierz dział z listy rozwijanej i kliknij pozycję Filtr:
Tym razem pierwszym punktem przerwania będzie zapytanie dla działów dla listy rozwijanej. Pomiń tę zmienną query
i wyświetl zmienną przy następnym osiągnięciu punktu przerwania, aby zobaczyć, jak Course
wygląda teraz zapytanie. Zobaczysz coś podobnego do następującego:
{SELECT
[Extent1].[CourseID] AS [CourseID],
[Extent1].[Title] AS [Title],
[Extent1].[Credits] AS [Credits],
[Extent1].[DepartmentID] AS [DepartmentID],
[Extent2].[DepartmentID] AS [DepartmentID1],
[Extent2].[Name] AS [Name],
[Extent2].[Budget] AS [Budget],
[Extent2].[StartDate] AS [StartDate],
[Extent2].[PersonID] AS [PersonID],
[Extent2].[Timestamp] AS [Timestamp]
FROM [Course] AS [Extent1]
INNER JOIN [Department] AS [Extent2] ON [Extent1].[DepartmentID] = [Extent2].[DepartmentID]
WHERE (@p__linq__0 IS NULL) OR ([Extent1].[DepartmentID] = @p__linq__1)}
Widać, że zapytanie jest teraz zapytaniem JOIN
, które ładuje Department
dane wraz z Course
danymi i że zawiera klauzulę WHERE
.
Praca z klasami serwerów proxy
Gdy program Entity Framework tworzy wystąpienia jednostek (na przykład podczas wykonywania zapytania), często tworzy je jako wystąpienia dynamicznie generowanego typu pochodnego, który działa jako serwer proxy dla jednostki. Ten serwer proxy zastępuje niektóre właściwości wirtualne jednostki w celu wstawiania punktów zaczepienia do wykonywania akcji automatycznie po korzystaniu z właściwości. Na przykład ten mechanizm służy do obsługi leniwego ładowania relacji.
Przez większość czasu nie musisz pamiętać o tym używaniu serwerów proxy, ale istnieją wyjątki:
- W niektórych scenariuszach możesz uniemożliwić programowi Entity Framework tworzenie wystąpień serwera proxy. Na przykład serializowanie wystąpień innych niż proxy może być bardziej wydajne niż serializowanie wystąpień serwera proxy.
- Podczas tworzenia wystąpienia klasy jednostki przy użyciu
new
operatora nie uzyskujesz wystąpienia serwera proxy. Oznacza to, że nie uzyskujesz funkcji, takich jak leniwe ładowanie i automatyczne śledzenie zmian. Jest to zwykle w porządku; zwykle nie potrzebujesz leniwego ładowania, ponieważ tworzysz nową jednostkę, która nie znajduje się w bazie danych, i zwykle nie potrzebujesz śledzenia zmian, jeśli jawnie oznaczysz jednostkę jakoAdded
. Jeśli jednak potrzebujesz opóźnionego ładowania i potrzebujesz śledzenia zmian, możesz utworzyć nowe wystąpienia jednostek z serwerami proxy przy użyciuCreate
metodyDbSet
klasy . - Możesz chcieć uzyskać rzeczywisty typ jednostki z typu serwera proxy. Możesz użyć
GetObjectType
metodyObjectContext
klasy, aby uzyskać rzeczywisty typ jednostki wystąpienia typu serwera proxy.
Aby uzyskać więcej informacji, zobacz Praca z serwerami proxy w blogu zespołu programu Entity Framework.
Wyłączanie automatycznego wykrywania zmian
Program Entity Framework określa, w jaki sposób jednostka uległa zmianie (i w związku z tym które aktualizacje muszą być wysyłane do bazy danych), porównując bieżące wartości jednostki z oryginalnymi wartościami. Oryginalne wartości są przechowywane podczas wykonywania zapytań lub dołączania jednostki. Niektóre metody, które powodują automatyczne wykrywanie zmian, są następujące:
DbSet.Find
DbSet.Local
DbSet.Remove
DbSet.Add
DbSet.Attach
DbContext.SaveChanges
DbContext.GetValidationErrors
DbContext.Entry
DbChangeTracker.Entries
Jeśli śledzisz dużą liczbę jednostek i wielokrotnie wywołujesz jedną z tych metod w pętli, możesz uzyskać znaczne ulepszenia wydajności, tymczasowo wyłączając automatyczne wykrywanie zmian przy użyciu właściwości AutoDetectChangesEnabled . Aby uzyskać więcej informacji, zobacz Automatyczne wykrywanie zmian.
Wyłączanie walidacji podczas zapisywania zmian
Podczas wywoływania SaveChanges
metody program Entity Framework domyślnie weryfikuje dane we wszystkich właściwościach wszystkich zmienionych jednostek przed zaktualizowaniem bazy danych. Jeśli zaktualizowano dużą liczbę jednostek i już zweryfikowano dane, ta praca jest niepotrzebna i możesz sprawić, że proces zapisywania zmian zajmie mniej czasu, tymczasowo wyłączając walidację. Można to zrobić przy użyciu właściwości ValidateOnSaveEnabled . Aby uzyskać więcej informacji, zobacz Walidacja.
Podsumowanie
Ta seria samouczków dotyczących korzystania z platformy Entity Framework w aplikacji MVC ASP.NET. Linki do innych zasobów programu Entity Framework można znaleźć na mapie zawartości dostępu do danych ASP.NET.
Aby uzyskać więcej informacji na temat wdrażania aplikacji internetowej po jej skompilowaniu, zobacz ASP.NET mapa zawartości wdrożenia w bibliotece MSDN.
Aby uzyskać informacje o innych tematach dotyczących wzorca MVC, takich jak uwierzytelnianie i autoryzacja, zobacz zalecane zasoby MVC.
Podziękowania
- Tom Dykstra napisał oryginalną wersję tego samouczka i jest starszym pisarzem programowania w zespole ds. zawartości Platforma Microsoft Web i narzędzi.
- Rick Anderson (twitter @RickAndMSFT) współtworzył ten samouczek i wykonał większość pracy aktualizując ją dla EF 5 i MVC 4. Rick jest starszym pisarzem programowania dla firmy Microsoft koncentrującym się na platformie Azure i MVC.
- Rowan Miller i inni członkowie zespołu Entity Framework pomagali w przeglądach kodu i pomagali debugować wiele problemów z migracjami, które pojawiły się podczas aktualizowania samouczka dla platformy EF 5.
VB
Po utworzeniu samouczka udostępniliśmy wersje języka C# i VB ukończonego projektu pobierania. Dzięki tej aktualizacji udostępniamy projekt do pobrania w języku C# dla każdego rozdziału, aby ułatwić rozpoczęcie pracy w dowolnym miejscu serii, ale ze względu na ograniczenia czasowe i inne priorytety nie zrobiliśmy tego dla języka VB. Jeśli tworzysz projekt VB przy użyciu tych samouczków i chcesz udostępnić go innym osobom, daj nam znać.
Błędy i obejścia
Nie można utworzyć/skopiować w tle
Komunikat o błędzie:
Nie można utworzyć/kopii w tle "DotNetOpenAuth.OpenId", gdy ten plik już istnieje.
Rozwiązanie 2.
Poczekaj kilka sekund i odśwież stronę.
Nie rozpoznano bazy danych Update-Database
Komunikat o błędzie:
Termin "Update-Database" nie jest rozpoznawany jako nazwa polecenia cmdlet, funkcji, pliku skryptu lub programu do obsługi. Sprawdź pisownię nazwy lub jeśli ścieżka została dołączona, sprawdź, czy ścieżka jest poprawna i spróbuj ponownie.(Z Update-Database
polecenia w pmc.)
Rozwiązanie 2.
Zamknij program Visual Studio. Otwórz ponownie projekt i spróbuj ponownie.
Walidacja nie powiodła się
Komunikat o błędzie:
Walidacja nie powiodła się dla co najmniej jednej jednostki. Aby uzyskać więcej informacji, zobacz właściwość EntityValidationErrors. (Z Update-Database
polecenia w pmc.)
Rozwiązanie 2.
Jedną z przyczyn tego problemu są błędy walidacji po uruchomieniu Seed
metody. Aby uzyskać porady dotyczące debugowania metody, zobacz Bazy danych programu Entity Framework (EF) dotyczące rozmieszczania i debugowania Seed
.
Błąd HTTP 500.19
Komunikat o błędzie:
Błąd HTTP 500.19 — wewnętrzny błąd serwera
Nie można uzyskać dostępu do żądanej strony, ponieważ powiązane dane konfiguracji strony są nieprawidłowe.
Rozwiązanie 2.
Jednym ze sposobów uzyskania tego błędu jest posiadanie wielu kopii rozwiązania, z których każdy korzysta z tego samego numeru portu. Zazwyczaj można rozwiązać ten problem, zamykając wszystkie wystąpienia programu Visual Studio, a następnie ponownie uruchamiając projekt, nad którym pracujesz. Jeśli to nie zadziała, spróbuj zmienić numer portu. Kliknij prawym przyciskiem myszy plik projektu, a następnie kliknij polecenie właściwości. Wybierz kartę Sieć Web , a następnie zmień numer portu w polu tekstowym Adres URL projektu.
Błąd podczas lokalizowania wystąpienia programu SQL Server
Komunikat o błędzie:
Podczas nawiązywania połączenia z serwerem SQL wystąpił błąd dotyczący sieci lub wystąpienia. Serwer nie został znaleziony lub był niedostępny. Sprawdź, czy nazwa wystąpienia jest prawidłowa oraz czy program SQL Server skonfigurowano tak, aby zezwalał na połączenia zdalne. (dostawca: interfejsy sieciowe SQL, błąd: 26 — Błąd podczas lokalizowania określonego serwera/wystąpienia)
Rozwiązanie 2.
Sprawdź parametry połączenia. Jeśli baza danych została ręcznie usunięta, zmień nazwę bazy danych w ciągu konstrukcyjnym.