OData WebAPI实践-OData与EDM

yizhihongxing

本文属于 OData 系列

引言

在 OData 中,EDM(Entity Data Model) 代表“实体数据模型”,它是一种用于表示 Web API 中的结构化数据的格式。EDM 定义了可以由 OData 服务公开的数据类型、实体和关系。 EDM 也提供了一些规则来描述数据模型中的实体之间的关系,例如继承、关联和复合类型。EDM 是 OData 协议的核心组成部分之一,它允许客户端和服务器之间以一致的方式交换和操作数据。

EDM 与实体对象模型

我刚接触 EDM 时恰好是与 EF Core 一起使用,就非常不理解这个现象:明明已经在 EF Core 中已经定义了模型,为啥还需要单独配置一个 EDM?

其实,EDM 和实体框架(EF)Core 中的实体对象虽然都用于数据建模,但却是不同的概念:在 EF Core 中,实体对象表示数据库中的表或视图,而 EDM 定义了 OData 服务中的数据结构,包括实体、属性、导航属性等。可以理解实体对象是为数据库服务,而 EDM 是用于数据开放服务的

虽然 EDM 和 EF Core 中的实体对象都具有一些相似之处,例如它们都有属性和关系,甚至你也可以直接返回实体模型用提供给 OData 让其动态自动生成 EDM 模型(Non-ODM 模式),但是依然建议使用 EDM 模型,主要是有几个方面:

  1. 实体框架中的实体类可能包含与 OData 服务定义不同的属性。例如,实体框架中的实体类可能包含用于持久化和跟踪状态的属性,而这些属性可能并不需要在 OData 服务中公开。
  2. 实体框架中的实体类可能使用与 OData 服务定义不同的命名约定。例如,实体框架中的实体类可能使用 PascalCase(首字母大写)命名约定,而在 OData 服务中的 EDM 可以使用 camelCase(首字母小写)命名约定。
  3. 实体框架中的实体类可能包含与 OData 服务定义不同的数据结构。例如,联合主键的实现用于 OData 查询较为麻烦,可以配置 EDM 使得 OData 对外服务不使用联合主键。

EDM 配置

在配置 OData 时,我们需要在代码中提供 EDM 对象。

.AddRouteComponents(AuthorizeHelper.PREFIX, EdmHelper.GetEdmModels());

GetEdmModels 函数返回一个 IEdmModel 对象。

      public static IEdmModel GetEdmModels()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            var device = builder.EntitySet<DeviceInfo>("DeviceInfos").EntityType.HasKey(p => p.DeviceId);
			device.Action("Upload");
            builder.EnableLowerCamelCase();
            return builder.GetEdmModel();
        }

以上代码中对 DeviceInfo 类型定义了一个实体对象,其具有 DeviceId 作为主键,拥有一个名为 Upload 的 Action。并且对所有的 EDM 对象启用了 LowerCamelCase 支持。上面的感觉是挺简单的是吧,注意我们使用到了 ODataConventionModelBuilder 对象,这个对象帮助我们自动实现了很多配置内容。如果我们使用其他的方式就不那么简单了。实际上配置 EDM 总共有三种方式。

我一般只使用 Convention 的配置方法,因此这里引用官方网站的例子,详情请见 Introduction to the model builders - OData | Microsoft Learn

Explicit

如果模型通过 new EdmModel() 构建,那么构建的是无类型模型,相当于你不依赖现有的 CLR 类型凭空构建了一个模型。

public IEdmModel GetEdmModel()
{
    EdmModel model = new EdmModel();
    
	EdmEntityType customer = new EdmEntityType("WebApiDocNS", "Customer");
	customer.AddKeys(customer.AddStructuralProperty("CustomerId", EdmPrimitiveTypeKind.Int32));
	customer.AddStructuralProperty("Location", new EdmComplexTypeReference(address, isNullable: true));
	model.AddElement(customer);
	
	EdmEntityType order = new EdmEntityType("WebApiDocNS", "Order");
	order.AddKeys(order.AddStructuralProperty("OrderId", EdmPrimitiveTypeKind.Int32));
	order.AddStructuralProperty("Token", EdmPrimitiveTypeKind.Guid);
	model.AddElement(order);

    return model;
}

Non-convention

如果模型是依赖 new ODataModelBuilder() 构建,那么构建模型时可以依据现有的 CLR 对象进行构建,不过依然需要配置每一个属性、操作等。

public static IEdmModel GetEdmModel()
{
    var builder = new ODataModelBuilder();
    var customer = builder.EntityType<Customer>();
customer.HasKey(c => c.CustomerId);
customer.ComplexProperty(c => c.Location);
customer.HasMany(c => c.Orders);

	var order = builder.EntityType<Order>();
order.HasKey(o => o.OrderId);
order.Property(o => o.Token);
    return builder.GetEdmModel();
}

相当于前一种方法已经有了很大改进,我们可以依赖现有的结构,而不再需要手动去命名了。

Convention

更进一步,我们可以使用惯例 ( Convention )方式,模型依赖 new ODataConventionModelBuilder () 构建,这个是代码最少的,整个模型的配置按照 OData RESTful 惯例实现。

      public static IEdmModel GetEdmModels()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            var device = builder.EntitySet<DeviceInfo>("DeviceInfos").EntityType;
            return builder.GetEdmModel();
        }

Convention 涉及的内容很多,有机会以后会详细解释惯例生成 EDM 这种模式。

常用 EDM 配置

EDM 配置项目繁多,我们常用的有:

  • 配置实体(主键)
var device = builder.EntitySet<DeviceInfo>("DeviceInfos").EntityType;
  • 配置(集合) Action
//对于实体上的Action
device.Action("Upload");
//对于集合上的Action
device.Collection.Action("Upload");
  • 配置(集合) Function
//对于实体上的Function
device.Function("Data").Returns<string>();
//对于集合上的Function
device.Collection.Function("Data").Returns<string>();

对 Function 以及 Action 的详细介绍,请期待后续文章。

访问 EDM 模型

OData 服务提供了 $metadata 终结点,可以从服务的根 URL 后添加 $metadata 来访问。例如以下是一个可以直接访问的 EDM 模型,以 XML 形式提供:

http://services.odata.org/TripPinRESTierService/$metadata

此外,也可以使用某些工具(如 Microsoft 的 OData Connected Service)来自动生成客户端代码,并从服务中获取元数据。这些工具通常会从服务的根 URL 下载 $metadata 文件,并将其解析为客户端代码。

原文链接:https://www.cnblogs.com/podolski/archive/2023/05/11/17390887.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:OData WebAPI实践-OData与EDM - Python技术站

(0)
上一篇 2023年5月11日
下一篇 2023年5月11日

相关文章

  • C#实现的简单验证码识别实例

    下面是针对C#实现简单验证码识别的完整攻略: 1. 获取验证码图片 首先,需要下载验证码图片并将其保存到本地。可以使用下面的代码来实现: var webClient = new WebClient(); webClient.DownloadFile("http://example.com/captcha.png", "captc…

    C# 2023年6月7日
    00
  • C#实现Dictionary字典赋值的方法

    当我们需要在C#中使用字典Dictionary进行数据存储时,需要对字典进行赋值。本文将详细介绍C#实现Dictionary字典赋值的方法。 一、字典Dictionary的基本概念 字典Dictionary是C#中一种非常常用的数据结构,它可以让我们轻松实现关键字与值之间的映射,可以存储任意类型的键值对,并且可以根据Key进行索引。 在C#中,我们可以使用泛…

    C# 2023年5月15日
    00
  • C#实现的优酷真实视频地址解析功能(2014新算法)

    C#实现的优酷真实视频地址解析功能(2014新算法) 简介 优酷视频地址解析,指的是提取优酷视频的原始播放地址,以便用户可以直接使用其他播放器播放视频。C#实现的优酷视频地址解析功能可以实现对优酷视频的深层次解析。 实现步骤: 1. 解析视频信息 第一步是解析视频信息,也就是获取视频播放页面的html源代码。解析可通过HttpWebRequest或HttpC…

    C# 2023年5月31日
    00
  • C#如何操作Excel数据透视表

    C#操作Excel数据透视表需要使用Microsoft.Office.Interop.Excel命名空间,以下是详细攻略: 安装Microsoft Excel:在操作Excel之前,必须安装Microsoft Excel软件。如果已经安装则可以跳过该步骤。 添加引用:右击项目,选择“添加”->“引用”,在弹出的对话框中选择“COM”标签页,找到Micr…

    C# 2023年6月6日
    00
  • C# Linq的Single()方法 – 返回序列中的唯一元素

    C# Linq中Single()函数的完整攻略 Single()函数是C# Linq中的一个用于查询的函数,它返回一个序列中单个特定元素,如果序列包含多个元素,则会引发异常。这篇攻略会详细讲解Single()函数的用法,并提供一些示例来帮助读者理解。 语法 下面是Single()函数的语法: public static TSource Single<T…

    C# 2023年4月19日
    00
  • Visual C#类的定义及实现方法实例解析

    Visual C#类的定义及实现方法实例解析 什么是C#类? C#类是指数据结构和函数的结合体。它定义了一种数据类型,用于表示抽象和具体的概念。C#类通常包含属性、方法、构造函数、索引器、事件等成员。 如何定义C#类? 要定义一个C#类,你需要使用class关键字。 下面是一个简单的C#类定义实例: public class Person { private…

    C# 2023年6月6日
    00
  • .NET/C#利用反射调用含ref或out参数的方法示例代码

    下面是详细的攻略: 1. 了解反射 反射是一种在运行时获取类型信息的机制。使用反射可以在运行时获取如类的名称、属性的名称、方法的名称等信息。通过反射,可以在运行时动态地加载程序集,创建实例并调用其成员。 2. 获取类型信息 在利用反射调用含ref或out参数的方法之前,需要先获取到该方法所属的类型的信息。我们通过以下代码来获取类型信息: Type type …

    C# 2023年5月31日
    00
  • asp.net jscript 一句话木马

    首先需要说明的是,一句话木马是一种常用的网络攻击技巧,攻击者可以通过一行代码或一句话控制Web服务器或受害者的计算机。因此,开发人员和网站维护人员应谨慎对待这些类型的攻击。 “asp.net jscript一句话木马”是一种特定的一句话木马,其使用asp.net语法和jscript编写,以下是完整攻略: 获取asp.net jscript一句话木马 asp.…

    C# 2023年5月31日
    00
合作推广
合作推广
分享本页
返回顶部