OData v4 - Web API 輕量級應用(使用Entity Framwork)-Endpoint

OData(Open Data Protocol)是web的數據訪問協議,提供統一的查詢和操作數據集(CRUD: create, read, update和delete)。ASP.NET Web API 支持OData v3和v4,甚至v3的endpoint和v4的endpoint可以並行運行。本文所講內容是在Web API輕量級應用中,使用Entity Framework來實現後端數據庫,並實現支持CRUD操作的OData v4 endpoint。

參考資料:http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint

solution全覽


創建solution

http://blog.csdn.net/daimeisi123/article/details/46776725#t1 (與《OData v4 - Web API 輕量級應用(無Entity Framwork)》相同)

安裝NuGet包

http://blog.csdn.net/daimeisi123/article/details/46776725#t2(與《OData v4 - Web API 輕量級應用(無Entity Framwork)》相同)

創建Models

在Models文件夾下創建一個model (Product.cs)

public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
    }

其中Id是entity key,Client能夠通過Id查詢到product entities,如Id=5,查詢語句爲“http://localhost:40596/Products(5)”

使用Entity Framework(EF)

在本文中將使用EF來創建後端數據庫,當然這不是唯一的方法,我們也可以創建data-acces 層來將數據實體轉換位Models。

  • 安裝EF NuGet 包

Tools->NuGet Package Manager->Package Manager Console

PM>Install-Package EntityFramework

  • 配置Web.config

配置在本地運行時將調用的數據庫,一個LocalDB database。

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

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

其中“name="ProductsContext"是connection的名字。

  • 添加DbContext

在Models下添加ProductsContext

 public class DemoDbContext: DbContext
    {
        public DemoDbContext()
            : base("name=DemoDbContext") // Give the name of the connection string in Web.config
        {
        }
        public DbSet<Product> Products { get; set; }
    }

配置OData EndPoint

在App_Start/WebApiConfig.cs中配置OData。如果需要多個OData endpoints,需要分別創建路徑和prefix

  • 創建Entity Data Model(EDM)
  • 添加路徑(route)
//Creates an Entity Data Model (EDM). 
  ODataModelBuilder builder = new ODataConventionModelBuilder();
  builder.EntitySet<Product>("Products");
 //Adds a route (Tells Web API how to route HTTP requests to the endpoint. )
 config.MapODataServiceRoute(routeName: "ODataRoute", routePrefix: null, model: builder.GetEdmModel());

添加OData Controller

controller是用來處理HTTP請求的,每一個entity都有對應的controller。

public class ProductsController : ODataController
    {
        //Uses the DemoDbContext class to access the database using EF
        DemoDbContext db = new DemoDbContext();
        //Judge if the product with this key is exist.
        private bool ProductExists(int key)
        {
            return db.Products.Any(p => p.Id == key);
        }
        //Dispose of the DemoDbContext
        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }

        /** CRUD(Create, read, update, delete)**/
        [EnableQuery] //--Enables clients to modify the query(such as $filter, $sort, $page)
        public IQueryable<Product> Get() // The entire Products collection
        {
            return db.Products;
        }

        [EnableQuery]
        public SingleResult<Product> Get([FromODataUri] int key)  //Query a product by its key 
        {
            IQueryable<Product> result = db.Products.Where(p => p.Id == key);
            return SingleResult.Create(result);
        }
        // Add a new product to the database
        public async Task<IHttpActionResult> Post(Product product)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            db.Products.Add(product);
            await db.SaveChangesAsync();
            return Created(product);
        }
        //Updating an entity -- PATCH(A partial update)
        public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Product> product)// Delta<T> type to track the changes
        {
            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);
        }
        //Updating an entity -- PUT(Replaces the entire 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);
        }
        //Delete an entity
        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);
        }
    }    






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章