Microsoft.AspNetCore.OData - 自定义注释 $metadata

Microsoft.AspNetCore.OData - Custom annotations $metadata

有没有办法在 Edm 模型生成期间向 $metadata 添加复杂的自定义注释?

例子(下面的XML是.NET自动生成的):

<EntitySet Name="Persons" EntityType="MyNS.Person">
    <NavigationPropertyBinding Path="Contracts" Target="Contracts"/>
    <NavigationPropertyBinding Path="CreatedBy" Target="Users"/>
    <NavigationPropertyBinding Path="UpdatedBy" Target="Users"/>
    <Annotation Term="Org.OData.Capabilities.V1.ExpandRestrictions">
        <Record>
            <PropertyValue Property="Expandable" Bool="true"/>
            <PropertyValue Property="NonExpandableProperties">
                <Collection>
                    <NavigationPropertyPath>Contacts</NavigationPropertyPath>
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
</EntitySet>

我想添加一个复杂的注释(这是 SAPUI5 词汇表的一部分):

<EntitySet Name="Persons" EntityType="MyNS.Person">
    <NavigationPropertyBinding Path="Contracts" Target="Contracts"/>
    <NavigationPropertyBinding Path="CreatedBy" Target="Users"/>
    <NavigationPropertyBinding Path="UpdatedBy" Target="Users"/>
    <Annotation Term="Org.OData.Capabilities.V1.ExpandRestrictions">
        <Record>
            <PropertyValue Property="Expandable" Bool="true"/>
            <PropertyValue Property="NonExpandableProperties">
                <Collection>
                    <NavigationPropertyPath>Contacts</NavigationPropertyPath>
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>

    <!--
        ↓↓ This part ↓↓ 
    -->
    <Annotation Term="UI.LineItem">
        <Collection>
            <Record Type="UI.DataField">
                <PropertyValue Property="Value" Path="Name"/>
                <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
            </Record>
        </Collection>
    </Annotation>
</EntitySet>

到目前为止,我已经能够使用以下代码向 EdmElement 添加自定义属性:

var personElement = oEdmModel.EntityContainer.Elements.First();
var stringType = EdmCoreModel.Instance.GetString(true);
var value = new EdmStringConstant(stringType, "my custom value");
oEdmModel.SetAnnotationValue(personElement , "MyNS", "Name", value);

oEdmModel.DirectValueAnnotationsManager.SetAnnotationValue(a, "MyNamespace", "AdminOnly", new EdmBooleanConstant(EdmCoreModel.Instance.GetBoolean(false), true));

(来源:How do you declare a custom oData annotation


...但是找不到添加“复杂”注释类型的方法。

感谢您的帮助!

EdmModel model = new EdmModel();

// Entity Type
EdmEntityType person = new EdmEntityType("NS", "Person");
model.AddElement(person);

// EntityContainer
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
EdmEntitySet persons = container.AddEntitySet("Persons", person);
model.AddElement(container);

// Complex Type
EdmComplexType dataField = new EdmComplexType("UI", "DataField");
dataField.AddStructuralProperty("Value", EdmCoreModel.Instance.GetAnnotationPath(true));
model.AddElement(dataField);

// Term Type
EdmTerm term = new EdmTerm("UI", "LineItem", new EdmComplexTypeReference(dataField, true));
model.AddElement(term);

EdmRecordExpression record = new EdmRecordExpression(new EdmPropertyConstructor("Value", new EdmPathExpression("Name")));
EdmVocabularyAnnotation annotation = new EdmVocabularyAnnotation(persons, term, record);
annotation.SetSerializationLocation(model, EdmVocabularyAnnotationSerializationLocation.Inline); // no necessary
model.SetVocabularyAnnotation(annotation);

然后你可以调用“CsdlWriter.TryWriteCsdl”来编写CSDL并验证为:

<?xml version="1.0" encoding="utf-16"?>
<edmx:Edmx Version="4.0" xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx">
  <edmx:DataServices>
    <Schema Namespace="NS" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <EntityType Name="Person" />
      <EntityContainer Name="Default">
        <EntitySet Name="Persons" EntityType="NS.Person">
          <Annotation Term="UI.LineItem">
            <Record>
              <PropertyValue Property="Value" Path="Name" />
            </Record>
          </Annotation>
        </EntitySet>
      </EntityContainer>
    </Schema>
    <Schema Namespace="UI" xmlns="http://docs.oasis-open.org/odata/ns/edm">
      <ComplexType Name="DataField">
        <Property Name="Value" Type="Edm.AnnotationPath" />
      </ComplexType>
      <Term Name="LineItem" Type="UI.DataField" />
    </Schema>
  </edmx:DataServices>
</edmx:Edmx>