SAP学习笔记 - 开发44 - RAP开发 Managed App 建 Projection View,Provider Contract,用 redirected to 设定父子关系

上一章讲了 建Travel_M 表/Booking_M表/BookSuppl_M表,以及表间关系(Parent-Child)设定。

SAP学习笔记 - 开发43 - RAP开发 Managed App 准备 - 建Travel_M 表/Booking_M表/BookSuppl_M表,以及表间关系(Parent-Child)-CSDN博客

本章继续学习RAP开发的知识 - 建 Projection View。

在 Data Model View ( CDS View for BO Structure )基础上创建 Projection View ( CDS View for BO Projection )。

难点在于 Provider Contract,需要用 redirected to composition child / redirected to parent来理清它们之间的关系。

目录

1,CDS View for Projection

1-1,New Data Definition - Travel_M (Projection View)

a. Provider Contract 的主要选项

b. 关键选项详解

(1) transactional_query

(2) transactional_interface

(3) query

(4) 其他选项

c. 选择时机与最佳实践

d. 注意事项

e. 总结

1-2,New Data Definition - Booking_M (Projection View)

1-3,New Data Definition - BookSuppl_M (Projection View)

1-4,总结贴一下代码

a),Z04_PV_Travel_M 代码

b),Z04_PV_Booking_M 代码

c),Z04_PV_BookSuppl_M 代码 


下面是详细内容。

1,CDS View for Projection

上一章咱们把CDS View for BO Structure (也就是 data view entity)建好了。

在此基础上,咱们来做 Projection View。

1-1,New Data Definition - Travel_M (Projection View)

Projection View的建法,其实和Data Model View一样,就是选不同模板嘛,其他都一样。

SAP学习笔记 - 开发37 - RAP开发流程的具体步骤, 建表,Data Model View,Projection View,Service,Service Binding,Publish-CSDN博客

输入Name,Description,Referenced Object,点Next

 

选TR,点Next

 

选 Projection View > defineProjectionView,然后点Finish

 

- 出了个错,说缺 root keyword,那就加呗

ROOT keyword missing in "Z04_PV_TRAVEL_M", since "Z04_DV_TRAVEL_M" has the root property

 

- 然后又来了个警告,说是缺 Transactional Provider Contract,也加上

Transactional Provider Contract expected for Projection View Z04_PV_Travel_M.

这里深入看一下Provider Contract:

在 SAP RAP (ABAP RESTful Application Programming Model) 中,Provider Contract 定义了 OData 服务如何暴露实体(Entities)的行为和功能。transactional_query 是其中一种 Provider Contract 类型,主要用于支持事务性查询。以下是详细说明:


a. Provider Contract 的主要选项

RAP 中常见的 Provider Contract 选项包括:

Provider Contract 类型用途适用场景
transactional_query支持在事务中执行查询(允许读操作与后续的 CUD 操作在同一个事务中)需要确保查询数据与后续修改在同一事务中(如检查数据后立即更新)
transactional_interface提供完整的事务性 CRUD 操作(Create, Read, Update, Delete)标准的业务对象暴露,需支持事务性修改(如主数据维护)
query仅支持只读查询(无事务性修改能力)报表、分析类服务,不需要修改数据
interface仅暴露结构定义(无行为实现),需手动实现行为需要完全自定义行为逻辑时(如特殊校验或复杂处理)
abstract_entity定义抽象实体,供其他实体继承需要复用公共字段或逻辑时(如基类实体)

b. 关键选项详解

(1) transactional_query
  • 作用
    允许在同一个事务中执行查询和后续的修改操作(如先查询数据,再基于结果更新)。

  • 示例场景

    • 检查订单状态后立即标记为“已处理”。

    • 验证库存数量后扣减库存。

  • 代码示例

    abap

  • @AccessControl.authorizationCheck: #CHECK
    @EndUserText.label: 'Transactional Query for Orders'
    define behavior for ZI_OrderTP transactional query
    { 
      // 定义查询和操作
    }
(2) transactional_interface
  • 作用
    提供完整的 CRUD 操作(Create, Read, Update, Delete)及事务支持,是业务对象的默认选择。

  • 示例场景

    • 维护客户主数据(创建、修改、删除)。

    • 订单管理(支持全生命周期操作)。

  • 代码示例

    abap

  • define behavior for ZI_CustomerTP transactional interface
    {
      // 定义标准操作(create, update, delete, etc.)
    }
(3) query
  • 作用
    仅支持只读查询,无事务性修改能力,性能优于事务性选项。

  • 示例场景

    • 销售报表展示。

    • 数据分析看板。

  • 代码示例

    abap

  • define behavior for ZI_SalesReportTP query
    {
      // 仅定义查询
    }
(4) 其他选项
  • interface
    需手动实现所有行为逻辑(如 save_modifieddetermine_action 等),适合高度定制化需求。

  • abstract_entity
    定义公共字段(如 created_bycreated_at),供其他实体继承。


c. 选择时机与最佳实践

需求场景推荐 Provider Contract理由
需要查询后立即修改(事务一致性)transactional_query保证查询和修改在同一事务中完成。
标准业务对象(CRUD 操作)transactional_interface默认选项,支持完整事务性操作。
只读报表或分析query无事务开销,性能更高。
自定义复杂逻辑interface允许完全手动实现行为。
实体继承与复用abstract_entity提取公共字段或逻辑。

d. 注意事项

  1. 性能权衡

    • 事务性选项(如 transactional_query)会带来事务锁开销,只读场景优先用 query

  2. 一致性需求

    • 若需确保查询结果与后续操作的一致性(如避免脏读),必须用 transactional_query

  3. OData 暴露

    • Provider Contract 需与 Service Definition 中的实体暴露方式匹配(如 exposewith)。


e. 总结

  • transactional_query:用于需要查询与修改在同一事务中的场景。

  • 其他选项根据读写需求(如只读用 query)和事务需求(如完整 CRUD 用 transactional_interface)选择。

  • 抽象和自定义场景使用 abstract_entityinterface

 

同样的,再做一下 Booking_M, BookSuppl_M 的Projection View。

1-2,New Data Definition - Booking_M (Projection View)

这个同样也有下面这个Warning,但是这次做法有点儿不同,不是简单的加一个Provider Contract,而是通过Parent - Child 方式从 Travel_M 进行继承:

>Transactional Provider Contract expected for Projection View Z04_PV_Booking_M.

给 Projection View添加 Parent - Child 关系:

- Parent -> Child >_Booking: redirected to composition child Z04_PV_Booking_M,

- Child -> Parent >_Travel : redirected to parent Z04_PV_Travel_M

然后再Activate,Z04_PV_Booking_M 就不会再出Provider Contract Warning了。

 

同样的,再做一下 Booking_M, BookSuppl_M 的Projection View。

1-3,New Data Definition - BookSuppl_M (Projection View)

这个同样也有下面这个Warning,做法和Booking_M一样,不是简单的加一个Provider Contract,而是通过Parent - Child 方式从 Booking_M 进行继承:

>Transactional Provider Contract expected for Projection View Z04_PV_BookSuppl_M.

另外,从 BookSuppl_M 看 Travel_M,它俩之间也是有 redirect 关系的,也给加上这层关系:

>_Travel: redirected to Z04_PV_Travel_M

1-4,总结贴一下代码

a),Z04_PV_Travel_M 代码

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Data Definition for Z04_PV_Travel_M - Projection View'
@Metadata.ignorePropagatedAnnotations: true
define root view entity Z04_PV_Travel_M
  provider contract transactional_query as projection on Z04_DV_Travel_M
{
    key TravelId,
    AgencyId,
    CustomerId,
    BeginDate,
    EndDate,
    @Semantics.amount.currencyCode: 'CurrencyCode'
    BookingFee,
    @Semantics.amount.currencyCode: 'CurrencyCode'
    TotalPrice,
    CurrencyCode,
    Description,
    OverallStatus,
    CreatedBy,
    CreatedAt,
    LastChangedBy,
    LastChangedAt,
    /* Associations */
    _Agency,
    _Booking: redirected to composition child Z04_PV_Booking_M,
    _Currency,
    _Customer,
    _Status
}

b),Z04_PV_Booking_M 代码

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Data Definition for Z04_PV_Booking_M - Projection View'
@Metadata.ignorePropagatedAnnotations: true
define view entity Z04_PV_Booking_M
  as projection on Z04_DV_Booking_M
{
  key TravelId,
  key BookingId,
      BookingDate,
      CustomerId,
      CarrierId,
      ConnectionId,
      FlightDate,
      @Semantics.amount.currencyCode: 'CurrencyCode'
      FlightPrice,
      CurrencyCode,
      BookingStatus,
      LastChangedAt,
      /* Associations */
      _BookingSupplement : redirected to composition child Z04_PV_BookSuppl_M,
      _Booking_Status,
      _Carrier,
      _Connection,
      _Customer,
      _Travel            : redirected to parent Z04_PV_Travel_M
}

c),Z04_PV_BookSuppl_M 代码 

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Data Definition for Z04_PV_BookSuppl_M - Projection View'
@Metadata.ignorePropagatedAnnotations: true
define view entity Z04_PV_BookSuppl_M
  as projection on Z04_DV_BookSuppl_M
{
  key TravelId,
  key BookingId,
  key BookingSupplementId,
      SupplementId,
      @Semantics.amount.currencyCode: 'CurrencyCode'
      Price,
      CurrencyCode,
      LastChangedAt,
      /* Associations */
      _Booking : redirected to parent Z04_PV_Booking_M,
      _Supplement,
      _SupplementText,
      _Travel: redirected to Z04_PV_Travel_M
}

以上就是本篇的全部内容。

更多SAP顾问业务知识请点击下面目录链接或东京老树根的博客主页

https://blog.csdn.net/shi_ly/category_12216766.html

东京老树根-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值