Zaawansowane scenariusze platformy Entity Framework dla aplikacji internetowej MVC (10 z 10)
Autor : Tom Dykstra
Przykładowa aplikacja internetowa Contoso University pokazuje, jak utworzyć 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 przypadku większości tych tematów będziesz pracować ze stronami, które zostały już utworzone. Aby użyć nieprzetworzonych aktualizacji sql, utworzysz nową stronę, która aktualizuje liczbę środków na wszystkie kursy w bazie danych:
Aby użyć zapytania bez śledzenia, dodaj nową logikę walidacji do strony Edytowanie działu:
Wykonywanie nieprzetworzonych zapytań SQL
Interfejs API Code First platformy 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ą 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 ta metoda jest używana do pobierania typów jednostek.- Użyj polecenia Database.ExecuteSqlCommand dla poleceń innych niż zapytania.
Jedną z zalet korzystania z platformy Entity Framework jest uniknięcie zbyt ścisłego wiązania kodu z określoną metodą przechowywania danych. Robi to, generując zapytania i polecenia SQL dla Ciebie, co również zwalnia Cię od konieczności samodzielnego pisania. Istnieją jednak wyjątkowe scenariusze, gdy trzeba uruchomić 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 wykonania tej czynności 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 przy użyciu dodatkowych metod. Jednym ze sposobów osiągnięcia tego celu byłoby dodanie metody akceptującej zapytanie SQL. Następnie można określić dowolny rodzaj filtrowania lub sortowania w kontrolerze, na przykład klauzulę Where
, która zależy od sprzężeń lub podquerii. W tej sekcji dowiesz się, jak zaimplementować taką metodę.
Utwórz metodę GetWithRawSql
, dodając następujący kod do pliku GenericRepository.cs:
public virtual IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters).ToList();
}
W pliku 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 pliku 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 musisz użyć Database.SqlQuery
metody .
W pliku HomeController.cs zastąp instrukcję LINQ w About
metodzie 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 contoso University chcą mieć możliwość przeprowadzania zbiorczych zmian w bazie danych, takich jak zmiana liczby środków na każdy kurs. Jeśli uniwersytet ma dużą liczbę kursów, byłoby nieefektywne, aby pobrać je wszystkie jako jednostki i zmienić je indywidualnie. W tej sekcji zaimplementujesz stronę internetową, która umożliwia użytkownikowi określenie czynnika, za pomocą którego należy zmienić liczbę środków dla wszystkich kursów, 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 plik 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 pliku 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 pliku 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 będzie mieć wartość null, multiplier
a widok wyświetli puste pole tekstowe i przycisk przesyłania, jak pokazano na poprzedniej ilustracji.
Po kliknięciu przycisku Aktualizuj i uruchomieniu HttpPost
multiplier
metody wartość zostanie wprowadzona 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 ViewBag
, których dotyczy ten obiekt, wyświetla ten numer zamiast pola tekstowego i przycisk przesyłania, jak pokazano na poniższej ilustracji:
Utwórz widok w folderze Views\Course dla strony Aktualizuj środki 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 przycisk Update (Aktualizuj). Zostanie wyświetlona liczba wierszy, których dotyczy problem:
Kliknij przycisk Wstecz do listy, aby wyświetlić listę kursów ze zmienioną liczbą środków.
Aby uzyskać więcej informacji na temat nieprzetworzonych zapytań SQL, zobacz Nieprzetworzone zapytania SQL w blogu zespołu platformy Entity Framework.
zapytania No-Tracking
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 obiektami 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 kontekstowe są zwykle krótkotrwałe (nowy jest tworzony i usuwany dla każdego żądania) oraz kontekst, który odczytuje jednostkę, jest zwykle usuwany, zanim ta jednostka zostanie ponownie użyta.
Można określić, czy kontekst śledzi obiekty jednostki 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, które wyłączają śledzenie, co 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 zapobiegania temu 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 pliku DepartmentController.cs dodaj nową metodę, którą można wywołać z Edit
metod i Create
, aby upewnić się, że żadne dwa działy nie mają 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 bloku HttpPost
Edit
metody , aby wywołać tę nową metodę, try
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ę Edytowanie 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ę Edytuj dział 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.
" Stało się to z powodu następującej sekwencji zdarzeń:
- Metoda
Edit
wywołuje metodęValidateOneAdministratorAssignmentPerInstructor
, która pobiera wszystkie działy, które mają kim Abercrombie jako administratora. To powoduje, że departament angielski jest odczytywany. Ponieważ jest to dział edytowany, nie zgłoszono żadnego błędu. 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 pamięci pobranych przez zapytanie sprawdzania poprawności. Nie ma żadnej wady w tym celu, ponieważ nie będziesz aktualizować tej jednostki ani odczytywać jej ponownie w sposób, który skorzystałby z buforowania w pamięci.
W pliku 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 zostanie zwrócona 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 to wypróbować, przyjrzysz się prostemu zapytaniu, a następnie przyjrzysz się temu, co się z nim dzieje, dodając opcje takie chętne do ładowania, filtrowania i sortowania.
W obszarze 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 pliku GenericRepository.cs w return query.ToList();
instrukcjach i return orderBy(query).ToList();
metody Get
. 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 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 pliku 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.
Kolekcja SelectList
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 właściwości Department
nawigacji. Wyrażenie filtru zawsze zwraca wartość true
, 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. Kontynuuj przez pierwsze dwa razy, że kod trafia do punktu przerwania, aby strona jest wyświetlana w przeglądarce. Wybierz dział z listy rozwijanej, a następnie kliknij pozycję Filtruj:
Tym razem pierwszy punkt przerwania będzie dotyczyć zapytań działów dla listy rozwijanej. Pomiń tę i wyświetl zmienną query
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)}
Zobaczysz, ż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 wygenerowanego typu pochodnego, który działa jako serwer proxy jednostki. Ten serwer proxy zastępuje niektóre właściwości wirtualne jednostki, aby wstawić punkty 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.
W większości przypadków nie trzeba pamiętać o tym używaniu serwerów proxy, ale istnieją wyjątki:
- W niektórych scenariuszach warto 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 otrzymujesz 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 trzeba ładować się z opóźnieniem, ponieważ tworzysz nową jednostkę, która nie znajduje się w bazie danych, i zwykle nie potrzebujesz śledzenia zmian, jeśli jawnie oznaczasz 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 Artykuł Praca z serwerami proxy w blogu zespołu platformy Entity Framework.
Wyłączanie automatycznego wykrywania zmian
Struktura Entity Framework określa sposób zmiany jednostki (i dlatego aktualizacje muszą być wysyłane do bazy danych) przez porównanie bieżących wartości jednostki z oryginalnymi wartościami. Oryginalne wartości są przechowywane, gdy jednostka została zapytana lub dołączona. 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
Po wywołaniu 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, a dane zostały już zweryfikowane, ta praca jest niepotrzebna i proces zapisywania zmian zajmuje 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
Spowoduje to ukończenie tej serii samouczków dotyczących korzystania z platformy Entity Framework w aplikacji ASP.NET MVC. Linki do innych zasobów platformy 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 Mapowanie zawartości wdrożenia w bibliotece MSDN.
Aby uzyskać informacje o innych tematach związanych z mvC, takimi jak uwierzytelnianie i autoryzacja, zobacz zalecane zasoby MVC.
Podziękowania
- Tom Dykstra napisał oryginalną wersję tego samouczka i jest starszym pisarzem programowania w zespole zawartości platformy i narzędzi firmy Microsoft.
- 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 pomogli w przeglądach kodu i pomogli debugować wiele problemów z migracjami, które pojawiły się podczas aktualizowania samouczka dotyczącego 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 w języku VB. Jeśli utworzysz 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ć/skopiować kopii w tle "DotNetOpenAuth.OpenId", gdy ten plik już istnieje.
Rozwiązanie:
Poczekaj kilka sekund i odśwież stronę.
Update-Database nie rozpoznano
Komunikat o błędzie:
Termin "Update-Database" nie jest rozpoznawany jako nazwa polecenia cmdlet, funkcji, pliku skryptu lub programu możliwego do działania. 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:
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:
Jedną z przyczyn tego problemu są błędy walidacji po uruchomieniu Seed
metody. Aby uzyskać porady dotyczące debugowania metody, zobacz Seeding and Debugging Entity Framework (EF) DBs (Wypełnianie i debugowanie baz danych platformy Entity Framework (EF).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 dla strony są nieprawidłowe.
Rozwiązanie:
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. Ten problem można zwykle rozwiązać, 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 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:
Sprawdź parametry połączenia. Jeśli baza danych została ręcznie usunięta, zmień nazwę bazy danych w ciągu konstrukcji.
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla