Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

In this example, we will create a new domain entity called StudentTransportation. This entity will add an Ed-Fi Extension to the Student Enrollment interchange and will be exposed in Ed-Fi ODS / API through a new API resource called studentTransportations. It is assumed that the Ed-Fi ODS has been successfully downloaded and is running as in a local environment per the instructions in the Getting Started documentation.  

The steps can be summarized as:

Table of Contents
maxLevel2
minLevel2
includeStep \d+.*

Each step is outlined in detail, below. 

Anchor
step1
step1
Step 1. Author Ed-Fi Core Schema Extensions

Create an Extension to the Ed-Fi Core Schema, called EXTENSION-Ed-Fi-Core.xsd, and place it in the C:\Ed-Fi-ODS-Implementation\Extensions\Schemas folder. This Extension introduces new entity types for the StudentTransportation entity. It is important to note that core schema Extension file must be able to resolve the reference to the Ed-Fi Core Schema file.

Code Block
languagexml
titleEXTENSION-Ed-Fi-Core.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://ed-fi.org/0220" xmlns:ann="http://ed-fi.org/annotation" xmlns:altova="http://www.altova.com/xml-schema-extensions" targetNamespace="http://ed-fi.org/0220" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:include schemaLocation="..\..\..\Ed-Fi-ODS\Application\schema.codegen\Ed-Fi-Core.xsd"/>
    <xs:annotation>
        <xs:documentation>===== Sample Core Type Extensions =====</xs:documentation>
    </xs:annotation>
    <xs:complexType name="EXTENSION-StudentTransportation">
        <xs:annotation>
            <xs:documentation>New state-specific entity which specifies the buses that a student is expecting to use and the approximate distance.</xs:documentation>
            <xs:appinfo>
                <ann:TypeGroup>Domain Entity</ann:TypeGroup>
            </xs:appinfo>
        </xs:annotation>
        <xs:complexContent>
            <xs:extension base="ComplexObjectType">
                <xs:sequence>
                    <xs:element name="StudentReference" type="StudentReferenceType">
                        <xs:annotation>
                            <xs:documentation>Student associated with the buses.</xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="SchoolReference" type="SchoolReferenceType">
                        <xs:annotation>
                            <xs:documentation>School associated with the buses.</xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="AMBusNumber" type="EXTENSION-BusNumber">
                        <xs:annotation>
                            <xs:documentation>Bus number student rides in morning (AM)</xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="PMBusNumber" type="EXTENSION-BusNumber">
                        <xs:annotation>
                            <xs:documentation>Bus number student rides in afternoon (PM)</xs:documentation>
                        </xs:annotation>
                    </xs:element>
                    <xs:element name="EstimatedMilesFromSchool" type="EXTENSION-EstimatedMiles">
		        <xs:annotation>
                            <xs:documentation>The distance the child lives from the school. Example, 1 Mile = 01.00  2.5 Miles = 02.50</xs:documentation>
                        </xs:annotation>
                    </xs:element>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    <xs:simpleType name="EXTENSION-BusNumber">
        <xs:annotation>
            <xs:documentation>Bus number student rides (see EXTENSION-StudentTransportation - used for AM and PM bus numbers)</xs:documentation>
            <xs:appinfo>
                <ann:TypeGroup>Simple</ann:TypeGroup>
            </xs:appinfo>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:minLength value="0"/>
            <xs:maxLength value="6"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="EXTENSION-EstimatedMiles">
        <xs:annotation>
            <xs:documentation>Estimated distance from point A to point B. (see EXTENSION-StudentTransporation)</xs:documentation>
            <xs:appinfo>
                <ann:TypeGroup>Simple</ann:TypeGroup>
            </xs:appinfo>
        </xs:annotation>
        <xs:restriction base="xs:decimal">
            <xs:minInclusive value="0.00"/>
            <xs:maxInclusive value="999.00"/>
            <xs:totalDigits value="5"/>
            <xs:fractionDigits value="2"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>


Info

For more information about how to extend the Ed-Fi Core Schema, see XML Schema - Extensions Framework Guide.

Anchor
step2
step2
Step 2. Author a Custom Interchange Schema

Create a custom interchange file, called EXTENSION-Interchange-StudentEnrollment.xsd, and place it in the C:\Ed-Fi-ODS-Implementation\Extensions\Schemas folder. This file overrides the Ed-Fi Student Enrollment Interchange, adding in the StudentTransportation entity into the Interchange. It is important to note that the schemaLocation should be a valid reference the schema file that contains the Extension definition (i.e., the EXTENSION-Ed-Fi-Core.xsd file created in the previous step).

Code Block
languagexml
titleEXTENSION-Interchange-StudentEnrollment.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://ed-fi.org/0220" targetNamespace="http://ed-fi.org/0220" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:include schemaLocation=".\EXTENSION-Ed-Fi-Core.xsd"/>
    <xs:annotation>
        <xs:documentation>===== Student Enrollment Interchange Model  =====</xs:documentation>
    </xs:annotation>
    <xs:element name="InterchangeStudentEnrollment">
    <xs:annotation>
        <xs:documentation>The Student Enrollment interchange describes student enrollments in schools and in sections.</xs:documentation>
    </xs:annotation>
    <xs:complexType>
        <xs:choice maxOccurs="unbounded">
            <xs:element name="SectionReference" type="SectionReferenceType"/>
            <xs:element name="StudentSchoolAssociation" type="StudentSchoolAssociation"/>
            <xs:element name="StudentSectionAssociation" type="StudentSectionAssociation"/>
            <xs:element name="GraduationPlan" type="GraduationPlan"/>
            <xs:element name="StudentEducationOrganizationAssociation" type="StudentEducationOrganizationAssociation"/>
            <xs:element name="StudentTransportation" type="EXTENSION-StudentTransportation"/>
        </xs:choice>
    </xs:complexType>
    </xs:element>
</xs:schema>


Info

For more information about how to create a custom interchange schema, see XML Schema - Custom Interchange Schema.

Anchor
step3
step3
Step 3. Author Database Schema Extensions

Create an Extension SQL script called 0001-Extensions.sql and place it in the C:\Ed-Fi-ODS-Implementation\Database\Structure\EdFi folder. This script defines the database schema for the Extension.

Code Block
languagesql
title0001-Extensions.sql
IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = 'extension')
BEGIN
    EXEC('CREATE SCHEMA [extension] AUTHORIZATION dbo')
END
GO
  
IF OBJECT_ID('extension.FK_StudentTransportation_SchoolId') IS NOT NULL
    ALTER TABLE extension.StudentTransportation DROP CONSTRAINT FK_StudentTransportation_SchoolId;
  
IF OBJECT_ID('extension.FK_StudentTransportation_StudentUSI') IS NOT NULL
    ALTER TABLE extension.StudentTransportation DROP CONSTRAINT FK_StudentTransportation_StudentUSI;
  
IF EXISTS (SELECT 1 FROM sys.tables WHERE SCHEMA_NAME(schema_id) = 'extension' AND OBJECT_NAME(object_id) = 'StudentTransportation')
    DROP TABLE extension.StudentTransportation;
  
IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE SCHEMA_NAME(schema_id) = 'extension' AND OBJECT_NAME(object_id) = 'StudentTransportation')
BEGIN
    CREATE TABLE extension.StudentTransportation (
        Id uniqueidentifier NOT NULL CONSTRAINT StudentTransportation_DF_Id DEFAULT newid()
        ,SchoolId INT NOT NULL
        ,StudentUSI INT NOT NULL
        ,AMBusNumber VARCHAR(6) CONSTRAINT StudentTransportation_DF_AMBusNumber DEFAULT '-' NOT NULL
        ,PMBusNumber VARCHAR(6) CONSTRAINT StudentTransportation_DF_PMBusNumber DEFAULT '-' NOT NULL
        ,EstimatedMilesFromSchool DECIMAL(5,2) NOT NULL
        ,CreateDate datetime NOT NULL CONSTRAINT StudentTransportation_DF_CreateDate DEFAULT getdate()
        ,LastModifiedDate datetime NOT NULL CONSTRAINT StudentTransportation_DF_LastModifiedDate DEFAULT getdate()
        ,CONSTRAINT StudentTransportation_PK PRIMARY KEY CLUSTERED (SchoolId,StudentUSI,AMBusNumber,PMBusNumber)
        ,CONSTRAINT FK_StudentTransportation_SchoolId FOREIGN KEY (SchoolId) REFERENCES edfi.School (SchoolId)
        ,CONSTRAINT FK_StudentTransportation_StudentUSI FOREIGN KEY (StudentUSI) REFERENCES edfi.Student (StudentUSI)
    )         
    CREATE UNIQUE NONCLUSTERED INDEX GUID_StudentTransportation ON extension.StudentTransportation (Id);
END
GO
 
EXEC sys.sp_addextendedproperty 'MS_Description', 'A designation of the transportation a student uses to get to and from school.', 'schema', 'extension', 'table', 'StudentTransportation'
GO


Info

When modeling the Ed-Fi Extension database tables, it is important to follow the patterns that already exist in the database.

Anchor
step4
step4
Step 4. Author API Metadata Extensions

Create an Extension API metadata file called DomainMetadata-Extension.xml and place it in the C:\Ed-Fi-ODS-Implementation\Extensions\Metadata folder. This file will register the StudentTransportation entity as a domain aggregate and ensure the code generation process will process the entity.

Code Block
languagexml
titleDomainMetadata-Extension.xml
<?xml version="1.0" encoding="utf-8" ?>
<AggregateExtensions>
    <Aggregate root="StudentTransportation">
        <Entity table="StudentTransportation" schema="extension" />
    </Aggregate>
</AggregateExtensions>

Anchor
step5
step5
Step 5. Run Code Generation and Verify Changes 

Re-run the code generation steps outlined in the Getting Started Guide, (i.e., from a PowerShell prompt run Initialize-PowershellForDevelopment.ps script, followed by the initdev command). Then run the application and view the Ed-Fi ODS / API using Swagger. The following new API resource should be visible:


Panel
borderColor#fec43d
bgColor#ffedc4
titleColor#000
borderWidth1
titleBGColor#fec43d
borderStylesolid
titleDownloads

The following link is a ZIP archive containing source files for this extensibility sample.

Student Transportation Source Files