ABP理论学习之OData集成(新增)

时间:2022-09-03 08:14:28

返回总目录


本篇目录

介绍###

OData其官网的定义是:

允许以一种 简单且标准的方式创建和使用可查询的、可互操作的RESTful APIs。

在ABP中也可以使用OData。Abp.Web.Api.OData nuget包简化了它的使用。

安装###

安装Nuget包

我们应该首先将Abp.Web.Api.OData nuget包安装到WebApi项目中:

Install-Package Abp.Web.Api.OData

设置模块依赖

给我们的WebApi项目设置的模块设置AbpWebApiODataModule的依赖。例如:

[DependsOn(typeof(AbpWebApiODataModule))]
public class MyProjectWebApiModule : AbpModule
{
...
}

请查看模块系统来理解模块依赖。

配置实体类

OData要求声明那些可以用作OData资源的实体。我们应该在WebApi项目模块的PreInitialize方法中处理这件事,如下所示:

[DependsOn(typeof(AbpWebApiODataModule))]
public class MyProjectWebApiModule : AbpModule
{
public override void PreInitialize()
{
var builder = Configuration.Modules.AbpWebApiOData().ODataModelBuilder; //Configure your entities here...
builder.EntitySet<Person>("People");
} ...
}

这里,我们得到了ODataModelBuilder的引用并设置了Person实体。类似地,你可以使用EntitySet来添加其他的实体。这里格外需要注意的是,括号里面的字符串People是指的控制器的前缀,这里我的控制器是PeopleController,当然你也可以设置为Persons等,我这里只是想说明要填的字符串更数据库的表名和自己定义的实体名没有关系。

查看使用ASP.NET Web API 2创建OData v4 终结点获取更多关于builder的信息。

创建控制器###

Abp.Web.Api.OData nuget包 包括了AbpODataEntityController基类(它扩展了标准的ODataController),这样就可以更容易地创建控制器了。下面是一个为Person实体创建一个OData终端(endpoint)的例子:

public class PersonsController : AbpODataEntityController<Person>
{
public PersonsController(IRepository<Person> repository)
: base(repository)
{
}
}

就是这么简单,AbpODataEntityController的所有方法都是virtual声明的。这意味着你可以重写 ** Get, Post, Put, Patch, Delete**和其他的action方法以及添加自己的逻辑。

例子###

下面看一个例子:

我的应用的端口是:localhost:61759。这里我只演示一些基本的东西,因为OData是一个标准的协议,所以你可以在网上轻松地找到更高级的例子。

数据库中People表的数据如下图:

ABP理论学习之OData集成(新增)

获取实体列表

这里我来获取所有的Person:

ABP理论学习之OData集成(新增)

获取单个实体

获取Id=2的那个Person的数据:

ABP理论学习之OData集成(新增)

获取具有导航属性的单个实体

修改实体类的定义,重新定义如下:

Person实体的定义:

namespace ABPMVCTest.Entities
{
[Table("Persons")]
public class Person:Entity
{
public virtual string Name { get; set; }
public virtual bool Gender { get; set; }
public virtual string UserName { get; set; }
public virtual ICollection<Car> Cars { get; set; } public Person()
{
} public Person(string name, params Car[] cars)
{
Name = name;
if (cars!=null)
{
Cars=new Collection<Car>();
foreach (var car in cars)
{
car.Person = this;
Cars.Add(car);
}
}
}
}
}

Car实体的定义:

namespace ABPMVCTest.Entities
{
[Table("Cars")]
public class Car:Entity
{
public virtual Person Person{ get; set; }
public virtual int PersonId { get; set; }
public virtual CarBrand Brand { get; set; }
public virtual int Price{ get; set; } public Car()
{
} public Car(CarBrand brand, int price)
{
Brand = brand;
Price = price;
}
}
}

CarBrand(汽车品牌)实体的定义:

namespace ABPMVCTest.Entities
{
public enum CarBrand
{
Jeep,
Buick,
Lincoln,
Kia,
LandRover
}
}

修改实体类之后,接下来给数据库填充数据。新增了3个人,Id分别是7,6,9;在Car表中分别给这三个人分配了汽车,如下图:

ABP理论学习之OData集成(新增)

ABP理论学习之OData集成(新增)

比如获取小明(Id=7)的数据,它具有一个Car导航属性,该属性代表此人的汽车对象:

ABP理论学习之OData集成(新增)

查询

下面将数据库的数据进行修改,如下图:

Persons表的数据:

ABP理论学习之OData集成(新增)

Cars表的数据:

ABP理论学习之OData集成(新增)

这里演示一个更高级的查询,包括过滤,排序和获取前2个结果,借助postman来演示:

查询条件是:Id<4,OrderBy UserName Desc,取前两条数据

请求

http://localhost:61759/odata/People?$filter=Id lt 4&$orderby=UserName&$top=2

响应

ABP理论学习之OData集成(新增)

可以看到,只过滤出来了小红和小刚的数据。

OData支持分页,排序,过滤,投影以及更多。

请查看官方文档获取更多信息。

创建一个新实体

在这个例子中,我们将创建一个新的Person,借助postman,很容易发送一个post请求。

请求

注意这里的报文头为Content-Type:"application/json"

ABP理论学习之OData集成(新增)

响应

ABP理论学习之OData集成(新增)

去数据库查看一下,发现已经多了一条刚才post的数据:

ABP理论学习之OData集成(新增)

当然了,我们也可以更新和删除实体,这里就不再做演示了,大家自行练习。

获取元数据【MetaData】

我们还可以获得实体的元数据,如下所示:

请求

http://localhost:61759/odata/$metadata

响应

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
<edmx:DataServices>
<Schema Namespace="ABPMVCTest.Entities" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityType Name="Person">
<Key>
<PropertyRef Name="Id" /> </Key>
<Property Name="Name" Type="Edm.String" />
<Property Name="Gender" Type="Edm.Boolean" Nullable="false" />
<Property Name="UserName" Type="Edm.String" />
<Property Name="Id" Type="Edm.Int32" Nullable="false" />
<NavigationProperty Name="Cars" Type="Collection(ABPMVCTest.Entities.Car)" /> </EntityType>
<EntityType Name="Car">
<Key>
<PropertyRef Name="Id" /> </Key>
<Property Name="PersonId" Type="Edm.Int32" />
<Property Name="Brand" Type="ABPMVCTest.Entities.CarBrand" Nullable="false" />
<Property Name="Price" Type="Edm.Int32" Nullable="false" />
<Property Name="Id" Type="Edm.Int32" Nullable="false" />
<NavigationProperty Name="Person" Type="ABPMVCTest.Entities.Person">
<ReferentialConstraint Property="PersonId" ReferencedProperty="Id" /> </NavigationProperty> </EntityType>
<EnumType Name="CarBrand">
<Member Name="Jeep" Value="0" />
<Member Name="Buick" Value="1" />
<Member Name="Lincoln" Value="2" />
<Member Name="Kia" Value="3" />
<Member Name="LandRover" Value="4" /> </EnumType> </Schema>
<Schema Namespace="Default" xmlns="http://docs.oasis-open.org/odata/ns/edm">
<EntityContainer Name="Container">
<EntitySet Name="People" EntityType="ABPMVCTest.Entities.Person" /> </EntityContainer> </Schema> </edmx:DataServices> </edmx:Edmx>

样例项目###

你可以在Github上获得样例代码,点击查看