Szukaj…


Zainstaluj pakiety OData

Z menu Narzędzia wybierz Menedżer pakietów NuGet> Konsola menedżera pakietów. W oknie konsoli Menedżera pakietów wpisz:

Install-Package Microsoft.AspNet.Odata

To polecenie instaluje najnowsze pakiety OData NuGet.

Włącz środowisko encji

W tym samouczku wykorzystamy kod Entity Framework (EF) Najpierw do utworzenia wewnętrznej bazy danych.

Web API OData nie wymaga EF. Użyj dowolnej warstwy dostępu do danych, która może tłumaczyć jednostki bazy danych na modele.

Najpierw zainstaluj pakiet NuGet dla EF. Z menu Narzędzia wybierz NuGet Package Manager > Konsola Menedżera pakietów . W oknie konsoli Menedżera pakietów wpisz:

Install-Package EntityFramework

Otwórz plik Web.config i dodaj następującą sekcję w elemencie konfiguracji , po elemencie configSections .

<configuration>
  <configSections>
    <!-- ... -->
  </configSections>

  <!-- Add this: -->
  <connectionStrings>
    <add name="ProductsContext" connectionString="Data Source=(localdb)\v11.0; 
        Initial Catalog=ProductsContext; Integrated Security=True; MultipleActiveResultSets=True; 
        AttachDbFilename=|DataDirectory|ProductsContext.mdf"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

To ustawienie dodaje parametry połączenia dla bazy danych LocalDB. Ta baza danych będzie używana podczas lokalnego uruchamiania aplikacji.

Następnie dodaj klasę o nazwie ProductsContext do folderu Modele:

using System.Data.Entity;
namespace ProductService.Models
{
    public class ProductsContext : DbContext
    {
        public ProductsContext() 
                : base("name=ProductsContext")
        {
        }
        public DbSet<Product> Products { get; set; }
    }
}

W konstruktorze „name = ProductsContext” podaje nazwę ciągu połączenia.

Skonfiguruj punkt końcowy OData

Otwórz plik App_Start / WebApiConfig.cs. Dodaj następujące instrukcje na podstawie:

using ProductService.Models;
using System.Web.OData.Builder;
using System.Web.OData.Extensions;

Następnie dodaj następujący kod do metody Register :

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // New code:
        ODataModelBuilder builder = new ODataConventionModelBuilder();
        builder.EntitySet<Product>("Products");
        config.MapODataServiceRoute(
            routeName: "ODataRoute",
            routePrefix: null,
            model: builder.GetEdmModel());
    }
}

Ten kod ma dwie rzeczy:

  • Tworzy model danych encji (EDM).
  • Dodaje trasę.

EDM to abstrakcyjny model danych. EDM służy do tworzenia dokumentu metadanych usługi. Klasa ODataConventionModelBuilder tworzy EDM przy użyciu domyślnych konwencji nazewnictwa. To podejście wymaga najmniejszego kodu. Jeśli chcesz mieć większą kontrolę nad EDM, możesz użyć klasy ODataModelBuilder do utworzenia EDM poprzez jawne dodanie właściwości, kluczy i właściwości nawigacji.

Trasa informuje interfejs API sieci Web, jak kierować żądania HTTP do punktu końcowego. Aby utworzyć trasę OData v4, wywołaj metodę rozszerzenia MapODataServiceRoute .

Jeśli aplikacja ma wiele punktów końcowych OData, utwórz osobną trasę dla każdego z nich. Nadaj każdej trasie unikalną nazwę i prefiks.

Dodaj kontroler OData

Kontroler to klasa, która obsługuje żądania HTTP. Tworzysz osobny kontroler dla każdego zestawu jednostek w usłudze OData. W tym samouczku utworzysz jeden kontroler dla encji Produkt.

W Eksploratorze rozwiązań kliknij prawym przyciskiem myszy folder Kontrolery i wybierz Dodaj > Klasa . Nazwij klasę ProductsController.

Wersja tego samouczka dla OData v3 wykorzystuje rusztowanie Add Controller. Obecnie nie ma rusztowania dla OData v4.

Zamień kod płyty grzewczej w ProductsController.cs na następujący.

using ProductService.Models;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.OData;
namespace ProductService.Controllers
{
    public class ProductsController : ODataController
    {
        ProductsContext db = new ProductsContext();
        private bool ProductExists(int key)
        {
            return db.Products.Any(p => p.Id == key);
        } 
        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}

Kontroler używa klasy ProductsContext, aby uzyskać dostęp do bazy danych za pomocą EF. Zauważ, że kontroler zastępuje metodę Dispose w celu usunięcia Kontaktu Produktów .

To jest punkt wyjścia dla kontrolera. Następnie dodamy metody dla wszystkich operacji CRUD.

Wykonywanie CRUD na zestawie jednostek

Zapytanie o zestaw encji

Dodaj następujące metody do ProductsController .

[EnableQuery]
public IQueryable<Product> Get()
{
    return db.Products;
}

[EnableQuery]
public SingleResult<Product> Get([FromODataUri] int key)
{
    IQueryable<Product> result = db.Products.Where(p => p.Id == key);
    return SingleResult.Create(result);
}

Bezparametrowa wersja metody Get zwraca całą kolekcję Produktów. Metoda Get z parametrem klucza wyszukuje produkt według jego klucza (w tym przypadku właściwości Id).

Atrybut [EnableQuery] umożliwia klientom modyfikowanie zapytania za pomocą opcji zapytania, takich jak $ filter, $ sort i $ page. Aby uzyskać więcej informacji, zobacz Obsługa opcji zapytania OData .

Dodawanie encji do zestawu encji

Aby umożliwić klientom dodawanie nowego produktu do bazy danych, dodaj następującą metodę do ProductsController .

public async Task<IHttpActionResult> Post(Product product)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    db.Products.Add(product);
    await db.SaveChangesAsync();
    return Created(product);
}

Aktualizowanie encji

OData obsługuje dwie różne semantyki do aktualizacji encji, PATCH i PUT.

  • PATCH wykonuje częściową aktualizację. Klient określa tylko właściwości do aktualizacji.
  • PUT zastępuje cały byt.

Wadą PUT jest to, że klient musi wysłać wartości dla wszystkich właściwości w encji, w tym wartości, które się nie zmieniają. Specyfikacja OData stwierdza, że PATCH jest preferowany.

W każdym razie, oto kod dla obu metod PATCH i PUT:

public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> product)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    var entity = await db.Products.FindAsync(key);
    if (entity == null)
    {
        return NotFound();
    }
    product.Patch(entity);
    try
    {
        await db.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!ProductExists(key))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }
    return Updated(entity);
}

public async Task<IHttpActionResult> Put([FromODataUri] int key, Product update)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    if (key != update.Id)
    {
        return BadRequest();
    }
    db.Entry(update).State = EntityState.Modified;
    try
    {
        await db.SaveChangesAsync();
    }
    catch (DbUpdateConcurrencyException)
    {
        if (!ProductExists(key))
        {
            return NotFound();
        }
        else
        {
            throw;
        }
    }
    return Updated(update);
}

W przypadku PATCH kontroler używa typu Delta <T> do śledzenia zmian.

Usuwanie encji

Aby umożliwić klientom usunięcie produktu z bazy danych, dodaj następującą metodę do ProductsController .

public async Task<IHttpActionResult> Delete([FromODataUri] int key)
{
    var product = await db.Products.FindAsync(key);
    if (product == null)
    {
        return NotFound();
    }
    db.Products.Remove(product);
    await db.SaveChangesAsync();
    return StatusCode(HttpStatusCode.NoContent);
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow