关闭

OData v4 - Web API 轻量级应用(使用Entity Framwork)-Endpoint

标签: web api轻量级应用entity frameworkasp.net
394人阅读 评论(0) 收藏 举报
分类:

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






0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:15545次
    • 积分:365
    • 等级:
    • 排名:千里之外
    • 原创:10篇
    • 转载:25篇
    • 译文:8篇
    • 评论:1条
    文章分类
    最新评论