수색…


OData 패키지 설치

도구 메뉴에서 NuGet 패키지 관리자> 패키지 관리자 콘솔을 선택하십시오. 패키지 관리자 콘솔 창에서 다음을 입력하십시오.

Install-Package Microsoft.AspNet.Odata

이 명령은 최신 OData NuGet 패키지를 설치합니다.

엔터티 프레임 워크 사용

이 자습서에서는 Entity Framework (EF) 코드 우선을 사용하여 백 엔드 데이터베이스를 만듭니다.

웹 API OData에는 EF가 필요하지 않습니다. 데이터베이스 엔티티를 모델로 변환 할 수있는 데이터 액세스 계층을 사용하십시오.

먼저, EF 용 NuGet 패키지를 설치하십시오. 도구 메뉴에서 NuGet 패키지 관리자 > 패키지 관리자 콘솔을 선택하십시오. 패키지 관리자 콘솔 창에서 다음을 입력하십시오.

Install-Package EntityFramework

Web.config 파일을 열고 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>

이 설정은 LocalDB 데이터베이스에 대한 연결 문자열을 추가합니다. 이 데이터베이스는 앱을 로컬에서 실행할 때 사용됩니다.

그런 다음 ProductsContext 라는 클래스를 Models 폴더에 추가합니다.

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

생성자에서 "name = ProductsContext" 는 연결 문자열의 이름을 제공합니다.

OData 끝점 구성

App_Start / WebApiConfig.cs 파일을 엽니 다. 다음 using 문을 추가하십시오.

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

그런 다음 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());
    }
}

이 코드는 두 가지 작업을 수행합니다.

  • Entity Data Model (EDM)을 생성합니다.
  • 경로를 추가합니다.

EDM은 데이터의 추상 모델입니다. EDM은 서비스 메타 데이터 문서를 만드는 데 사용됩니다. ODataConventionModelBuilder 클래스는 기본 명명 규칙을 사용하여 EDM을 만듭니다. 이 접근법은 최소한의 코드가 필요합니다. EDM을보다 잘 제어하려는 경우 ODataModelBuilder 클래스를 사용하여 속성, 키 및 탐색 속성을 명시 적으로 추가하여 EDM을 만들 수 있습니다.

라우트는 HTTP 요청을 엔드 포인트로 라우트하는 f}을 웹 API에 알립니다. OData v4 라우트를 작성하려면 MapODataServiceRoute 확장 메소드를 호출하십시오.

애플리케이션에 여러 OData 엔드 포인트가있는 경우 각각에 대해 별도의 경로를 작성하십시오. 각 경로에 고유 한 경로 이름과 접두어를 지정하십시오.

OData 컨트롤러 추가

컨트롤러는 HTTP 요청을 처리하는 클래스입니다. OData 서비스의 각 엔터티 집합에 대해 별도의 컨트롤러를 만듭니다. 이 자습서에서는 Product 엔티티에 대해 하나의 컨트롤러를 만듭니다.

솔루션 탐색기에서 Controllers 폴더를 마우스 오른쪽 단추로 클릭하고 추가 > 클래스를 선택 하십시오 . ProductsController 클래스의 이름을 지정합니다.

OData v3에 대한이 자습서의 버전은 Add Controller 스캐 폴딩을 사용합니다. 현재 OData v4에 대한 스캐 폴딩은 없습니다.

ProductsController.cs의 상용구 코드를 다음으로 대체하십시오.

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

컨트롤러는 ProductsContext 클래스를 사용하여 EF를 사용하여 데이터베이스에 액세스합니다. 컨트롤러가 Dispose 메서드를 재정 의하여 ProductsContext 를 처리합니다.

이것은 컨트롤러의 시작점입니다. 다음으로 모든 CRUD 작업에 대한 메소드를 추가합니다.

엔티티 세트에서 CRUD 수행

엔티티 세트 쿼리

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

매개 변수없는 버전의 Get 메서드는 전체 Products 컬렉션을 반환합니다. 키 매개 변수가있는 Get 메서드는 해당 키 (이 경우 Id 속성)별로 제품을 조회합니다.

[EnableQuery] 특성을 사용하면 클라이언트가 $ filter, $ sort 및 $ page와 같은 쿼리 옵션을 사용하여 쿼리를 수정할 수 있습니다. 자세한 내용은 OData 쿼리 옵션 지원을 참조하십시오.

엔티티 집합에 엔티티 추가

클라이언트가 데이터베이스에 새 제품을 추가 할 수있게하려면 다음 메소드를 ProductsController에 추가하십시오.

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

엔티티 업데이트

OData는 엔터티, PATCH 및 PUT을 업데이트하는 두 가지 의미를 지원합니다.

  • PATCH가 부분 업데이트를 수행합니다. 클라이언트는 업데이트 할 속성 만 지정합니다.
  • PUT은 엔티티 전체를 대체합니다.

PUT의 단점은 클라이언트가 변경되지 않는 값을 포함하여 엔티티의 모든 속성에 대한 값을 보내야한다는 것입니다. OData 사양 에서는 PATCH가 선호됩니다.

어쨌든 다음은 PATCH 및 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);
}

PATCH의 경우 컨트롤러는 Delta <T> 유형을 사용하여 변경 사항을 추적합니다.

엔티티 삭제

클라이언트가 데이터베이스에서 제품을 삭제할 수있게하려면 다음 메소드를 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
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow