public void ConstructibleVocabularySerializingAnnotationsWithNoTerm()
        {
            var stockModel = new EdmModel();
            var customer = new EdmEntityType("NS1", "Customer");
            var customerId = customer.AddStructuralProperty("CustomerID", EdmCoreModel.Instance.GetString(false));
            customer.AddKeys(customerId);
            stockModel.AddElement(customer);

            var annotation = new MutableValueAnnotation()
            {
                Target = customer,
                Value = new EdmStringConstant("Hello world2!"),
            };
            stockModel.AddVocabularyAnnotation(annotation);

            var stringWriter = new StringWriter();
            var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings() { Indent = true });
            IEnumerable<EdmError> serializationErrors;
            stockModel.TryWriteCsdl(xmlWriter, out serializationErrors);
            xmlWriter.Close();

            Assert.AreEqual(1, serializationErrors.Count(), "Error on serialization");
        }
Example #2
0
        public static IEnumerable<XElement> SimpleAllPrimitiveTypes(EdmVersion edmVersion, bool explictNullable, bool isNullable)
        {
            var namespaceName = "ModelBuilder.SimpleAllPrimitiveTypes";

            var model = new EdmModel();
            var entityType = new EdmEntityType(namespaceName, "validEntityType1");
            entityType.AddKeys(entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, false));
            model.AddElement(entityType);

            var complexType = new EdmComplexType(namespaceName, "V1alidcomplexType");
            model.AddElement(complexType);

            int i = 0;
            bool typesAreNullable = !explictNullable && isNullable;
            foreach (var primitiveType in AllPrimitiveEdmTypes(edmVersion, typesAreNullable))
            {
                entityType.AddStructuralProperty("Property" + i++, primitiveType);
                complexType.AddStructuralProperty("Property" + i++, primitiveType);
            }

            var stringBuilder = new StringBuilder();
            var xmlWriter = XmlWriter.Create(stringBuilder);
            IEnumerable<EdmError> errors;
            if (!model.TryWriteCsdl((s) => xmlWriter, out errors) || errors.Any())
            {
                ExceptionUtilities.Assert(false, "Failed to write CSDL: " + string.Join(",", errors.Select(e => e.ErrorMessage)));
            }

            xmlWriter.Close();
            var csdlElements = new[] { XElement.Parse(stringBuilder.ToString()) };

            if (explictNullable)
            {
                ModelBuilderHelpers.SetNullableAttributes(csdlElements, isNullable);
            }

            return csdlElements;
        }
        public void ValidateSerializationBlockingErrors()
        {
            EdmModel model = new EdmModel();

            EdmComplexType complexWithBadProperty = new EdmComplexType("Foo", "Bar");
            complexWithBadProperty.AddProperty(new EdmStructuralProperty(complexWithBadProperty, "baz", new EdmComplexTypeReference(new EdmComplexType("", ""), false)));
            model.AddElement(complexWithBadProperty);

            EdmEntityType baseType = new EdmEntityType("Foo", "");
            IEdmStructuralProperty keyProp = new EdmStructuralProperty(baseType, "Id", EdmCoreModel.Instance.GetInt32(false));
            baseType.AddProperty(keyProp);
            baseType.AddKeys(keyProp);

            EdmEntityType derivedType = new EdmEntityType("Foo", "Quip", baseType);
            model.AddElement(baseType);
            model.AddElement(derivedType);
            EdmNavigationProperty navProp = derivedType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo(){ Name="navProp", Target=derivedType, TargetMultiplicity=EdmMultiplicity.One });

            EdmEntityContainer container = new EdmEntityContainer("Foo", "Container");
            model.AddElement(container);
            container.AddElement(new EdmEntitySet(container, "badNameSet", baseType));

            StringBuilder sb = new StringBuilder();
            IEnumerable<EdmError> errors;
            bool written = model.TryWriteCsdl(XmlWriter.Create(sb), out errors);
            var expectedErrors = new EdmLibTestErrors()
            {
                { "([. Nullable=False])", EdmErrorCode.ReferencedTypeMustHaveValidName },
                { "(Foo.Quip)", EdmErrorCode.ReferencedTypeMustHaveValidName },
                { "(Microsoft.OData.Edm.Library.EdmEntitySet)", EdmErrorCode.ReferencedTypeMustHaveValidName },
            };

            this.CompareErrors(errors, expectedErrors);
        }
        public void CsdlWriterShouldFailWithGoodMessageWhenWritingInvalidXml()
        {
            var model = new EdmModel();
            model.SetEdmVersion(Microsoft.OData.Edm.Library.EdmConstants.EdmVersion4);
            var fredFlintstone = new EdmComplexType("Flintstones", "Fred");
            fredFlintstone.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
            model.AddElement(fredFlintstone);

            // set annotation which will be serialzed (because the value is an IEdmValue) with a name that doesn't match the xml spec for NCName.
            model.SetAnnotationValue(fredFlintstone, "sap", "-contentversion", new EdmStringConstant(EdmCoreModel.Instance.GetString(false), "hello"));

            Assert.AreEqual(1, model.DirectValueAnnotations(fredFlintstone).Count(), "Wrong # of Annotations on {0}.", fredFlintstone);

            var stringWriter = new StringWriter();
            var xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings() { Indent = true });

            try
            {
                IEnumerable<EdmError> errors;
                model.TryWriteCsdl(xmlWriter, out errors);
                Assert.Fail("Excepted an exception when trying to serialize a direct value annotation which does not match the xml naming spec.");
            }
            catch (ArgumentException e)
            {
                Assert.AreEqual(e.Message, "Invalid name character in '-contentversion'. The '-' character, hexadecimal value 0x2D, cannot be included in a name.", "Expected exception message did not match.");
            }

            xmlWriter.Close();
        }
        public void TestCoreIsLanguageDependentAnnotation()
        {
            EdmModel model = new EdmModel();

            EdmEntityContainer container = new EdmEntityContainer("Ns", "Container");
            var personType = new EdmEntityType("Ns", "Person");
            var propertyId = personType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));
            personType.AddKeys(propertyId);
            var structuralProperty = personType.AddStructuralProperty("Concurrency", EdmCoreModel.Instance.GetInt32(true));
            model.AddElement(personType);
            var entitySet = container.AddEntitySet("People", personType);

            var stringTerm = new EdmTerm("Ns", "HomeAddress", EdmCoreModel.Instance.GetString(true));
            model.AddElement(stringTerm);
            model.AddElement(container);

            IEdmValueTerm term = CoreVocabularyModel.IsLanguageDependentTerm;
            IEdmBooleanConstantExpression trueExpression = new EdmBooleanConstant(true);
            IEdmBooleanConstantExpression falseExpression = new EdmBooleanConstant(false);

            EdmAnnotation personIdAnnotation = new EdmAnnotation(propertyId, term, trueExpression);
            personIdAnnotation.SetSerializationLocation(model, EdmVocabularyAnnotationSerializationLocation.Inline);
            model.SetVocabularyAnnotation(personIdAnnotation);

            EdmAnnotation structuralPropertyAnnotation = new EdmAnnotation(structuralProperty, term, falseExpression);
            structuralPropertyAnnotation.SetSerializationLocation(model, EdmVocabularyAnnotationSerializationLocation.Inline);
            model.SetVocabularyAnnotation(structuralPropertyAnnotation);

            EdmAnnotation stringTermAnnotation = new EdmAnnotation(stringTerm, term, trueExpression);
            stringTermAnnotation.SetSerializationLocation(model, EdmVocabularyAnnotationSerializationLocation.Inline);
            model.SetVocabularyAnnotation(stringTermAnnotation);

            var idAnnotationValue = (model.FindVocabularyAnnotations<IEdmValueAnnotation>(propertyId, term).FirstOrDefault().Value as IEdmBooleanConstantExpression).Value;
            var structuralPropertyAnnotationValue = (model.FindVocabularyAnnotations<IEdmValueAnnotation>(structuralProperty, term).FirstOrDefault().Value as IEdmBooleanConstantExpression).Value;
            var stringTermAnnotationValue = (model.FindVocabularyAnnotations<IEdmValueAnnotation>(stringTerm, term).FirstOrDefault().Value as IEdmBooleanConstantExpression).Value;
            var entitySetAnnotation = model.FindVocabularyAnnotations<IEdmValueAnnotation>(entitySet, term).FirstOrDefault();

            Assert.AreEqual(true, idAnnotationValue);
            Assert.AreEqual(false, structuralPropertyAnnotationValue);
            Assert.AreEqual(true, stringTermAnnotationValue);
            Assert.IsNull(entitySetAnnotation);

            const string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Schema Namespace=""Ns"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
  <EntityType Name=""Person"">
    <Key>
      <PropertyRef Name=""Id"" />
    </Key>
    <Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false"">
      <Annotation Term=""Org.OData.Core.V1.IsLanguageDependent"" Bool=""true"" />
    </Property>
    <Property Name=""Concurrency"" Type=""Edm.Int32"">
      <Annotation Term=""Org.OData.Core.V1.IsLanguageDependent"" Bool=""false"" />
    </Property>
  </EntityType>
  <Term Name=""HomeAddress"" Type=""Edm.String"">
    <Annotation Term=""Org.OData.Core.V1.IsLanguageDependent"" Bool=""true"" />
  </Term>
  <EntityContainer Name=""Container"">
    <EntitySet Name=""People"" EntityType=""Ns.Person"" />
  </EntityContainer>
</Schema>";

            IEnumerable<EdmError> errors;
            StringWriter sw = new StringWriter();
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            XmlWriter xw = XmlWriter.Create(sw, settings);
            model.TryWriteCsdl(xw, out errors);
            xw.Flush();
            xw.Close();
            var actual = sw.ToString();

            Assert.AreEqual(expected, actual);

            IEdmModel parsedModel;
            IEnumerable<EdmError> errs;
            bool parsed = CsdlReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(expected)) }, out parsedModel, out errs);
            Assert.IsTrue(parsed, "parsed");
            Assert.IsTrue(!errors.Any(), "No errors");

            var idAnnotation = parsedModel.FindVocabularyAnnotations<IEdmValueAnnotation>(propertyId, term).FirstOrDefault();
            var propertyAnnotation = parsedModel.FindVocabularyAnnotations<IEdmValueAnnotation>(structuralProperty, term).FirstOrDefault();
            var termAnnotation = parsedModel.FindVocabularyAnnotations<IEdmValueAnnotation>(stringTerm, term).FirstOrDefault();
            entitySetAnnotation = parsedModel.FindVocabularyAnnotations<IEdmValueAnnotation>(entitySet, term).FirstOrDefault();

            Assert.AreEqual(null, propertyAnnotation);
            Assert.AreEqual(null, idAnnotation);
            Assert.AreEqual(null, termAnnotation);
            Assert.AreEqual(null, entitySetAnnotation);

            var parsedPersonType = parsedModel.FindType("Ns.Person") as IEdmEntityType;
            idAnnotationValue = (parsedModel.FindVocabularyAnnotations<IEdmValueAnnotation>(parsedPersonType.FindProperty("Id"), term).FirstOrDefault().Value as IEdmBooleanConstantExpression).Value;
            structuralPropertyAnnotationValue = (parsedModel.FindVocabularyAnnotations<IEdmValueAnnotation>(parsedPersonType.FindProperty("Concurrency"), term).FirstOrDefault().Value as IEdmBooleanConstantExpression).Value;
            stringTermAnnotationValue = (parsedModel.FindVocabularyAnnotations<IEdmValueAnnotation>(parsedModel.FindValueTerm("Ns.HomeAddress"), term).FirstOrDefault().Value as IEdmBooleanConstantExpression).Value;
            entitySetAnnotation = parsedModel.FindVocabularyAnnotations<IEdmValueAnnotation>(parsedModel.FindDeclaredEntitySet("People"), term).FirstOrDefault();

            Assert.IsNotNull(parsedPersonType);
            Assert.AreEqual(false, structuralPropertyAnnotationValue);
            Assert.AreEqual(true, idAnnotationValue);
            Assert.AreEqual(true, stringTermAnnotationValue);
            Assert.IsNull(entitySetAnnotation);
        }
Example #6
0
        public void CheckNewModelHasNoVersion()
        {
            EdmModel model = new EdmModel();
            EdmEntityType t1 = new EdmEntityType("Bunk", "T1");
            EdmStructuralProperty p1 = t1.AddStructuralProperty("P1", EdmCoreModel.Instance.GetBoolean(false));
            EdmStructuralProperty p2 = t1.AddStructuralProperty("P2", EdmCoreModel.Instance.GetDecimal(1, 1, false));
            EdmStructuralProperty p3 = t1.AddStructuralProperty("P3", EdmCoreModel.Instance.GetTemporal(EdmPrimitiveTypeKind.Duration, 1, false));
            EdmStructuralProperty p4 = t1.AddStructuralProperty("P4", EdmCoreModel.Instance.GetBinary(false, 4, false));
            EdmStructuralProperty p5 = t1.AddStructuralProperty("P5", EdmCoreModel.Instance.GetBinary(false));
            IEdmStructuralProperty q1 = (IEdmStructuralProperty)t1.FindProperty("P1");
            IEdmStructuralProperty q2 = (IEdmStructuralProperty)t1.FindProperty("P2");
            IEdmStructuralProperty q3 = (IEdmStructuralProperty)t1.FindProperty("P3");
            IEdmStructuralProperty q4 = (IEdmStructuralProperty)t1.FindProperty("P4");
            IEdmStructuralProperty q5 = (IEdmStructuralProperty)t1.FindProperty("P5");
            model.AddElement(t1);

            Assert.IsNull(model.GetEdmVersion(), "Version is null");

            StringWriter sw = new StringWriter();
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            XmlWriter xw = XmlWriter.Create(sw, settings);
            IEnumerable<EdmError> errors;
            model.TryWriteCsdl(xw, out errors);
            xw.Flush();
            xw.Close();
            string outputText = sw.ToString();

            IEdmModel iEdmModel;
            bool parsed = CsdlReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(outputText)) }, out iEdmModel, out errors);
            Assert.IsTrue(parsed, "Model Parsed");
            Assert.IsTrue(errors.Count() == 0, "No errors");
            Assert.AreEqual(EdmConstants.EdmVersionLatest, iEdmModel.GetEdmVersion(), "Version check");
        }
        public void AnnotationValueAsEnumMemberReferenceExpressionSerializationTest()
        {
            EdmModel model = new EdmModel();

            EdmEntityContainer container = new EdmEntityContainer("Ns", "Container");
            var personType = new EdmEntityType("Ns", "Person");
            var propertyId = personType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));
            personType.AddKeys(propertyId);
            var structuralProperty = personType.AddStructuralProperty("Concurrency", EdmCoreModel.Instance.GetInt32(true));
            model.AddElement(personType);
            var entitySet = container.AddEntitySet("People", personType);
            var permissionType = new EdmEnumType("Ns", "Permissions", true);
            var read = permissionType.AddMember("Read", new EdmIntegerConstant(1));
            var write = permissionType.AddMember("Write", new EdmIntegerConstant(2));
            var delete = permissionType.AddMember("Delete", new EdmIntegerConstant(4));
            model.AddElement(permissionType);

            var enumTerm = new EdmTerm("Ns", "Permission", new EdmEnumTypeReference(permissionType, false));
            model.AddElement(enumTerm);
            model.AddElement(container);

            EdmAnnotation personIdAnnotation = new EdmAnnotation(propertyId, enumTerm, new EdmEnumMemberReferenceExpression(read));
            personIdAnnotation.SetSerializationLocation(model, EdmVocabularyAnnotationSerializationLocation.Inline);
            model.SetVocabularyAnnotation(personIdAnnotation);

            EdmAnnotation structuralPropertyAnnotation = new EdmAnnotation(structuralProperty, enumTerm, new EdmEnumMemberExpression(read, write));
            structuralPropertyAnnotation.SetSerializationLocation(model, EdmVocabularyAnnotationSerializationLocation.Inline);
            model.SetVocabularyAnnotation(structuralPropertyAnnotation);

            EdmAnnotation entitySetAnnotation = new EdmAnnotation(entitySet, enumTerm, new EdmEnumMemberReferenceExpression(delete));
            structuralPropertyAnnotation.SetSerializationLocation(model, EdmVocabularyAnnotationSerializationLocation.Inline);
            model.SetVocabularyAnnotation(entitySetAnnotation);

            var idAnnotationValue = (model.FindVocabularyAnnotations<IEdmValueAnnotation>(propertyId, enumTerm).FirstOrDefault().Value as IEdmEnumMemberReferenceExpression).ReferencedEnumMember;
            var structuralPropertyAnnotationValue = (model.FindVocabularyAnnotations<IEdmValueAnnotation>(structuralProperty, enumTerm).FirstOrDefault().Value as IEdmEnumMemberExpression).EnumMembers;
            var entitySetAnnotationValue = (model.FindVocabularyAnnotations<IEdmValueAnnotation>(entitySet, enumTerm).FirstOrDefault().Value as IEdmEnumMemberReferenceExpression).ReferencedEnumMember;
            var enumTypeAnnotationValue = model.FindVocabularyAnnotations<IEdmValueAnnotation>(permissionType, enumTerm).FirstOrDefault();

            Assert.AreEqual(read, idAnnotationValue);
            Assert.AreEqual(2, structuralPropertyAnnotationValue.Count());
            Assert.AreEqual(delete, entitySetAnnotationValue);
            Assert.IsNull(enumTypeAnnotationValue);

            const string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Schema Namespace=""Ns"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
  <EntityType Name=""Person"">
    <Key>
      <PropertyRef Name=""Id"" />
    </Key>
    <Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false"">
      <Annotation Term=""Ns.Permission"">
        <EnumMember>Ns.Permissions/Read</EnumMember>
      </Annotation>
    </Property>
    <Property Name=""Concurrency"" Type=""Edm.Int32"">
      <Annotation Term=""Ns.Permission"">
        <EnumMember>Ns.Permissions/Read Ns.Permissions/Write</EnumMember>
      </Annotation>
    </Property>
  </EntityType>
  <EnumType Name=""Permissions"" IsFlags=""true"">
    <Member Name=""Read"" Value=""1"" />
    <Member Name=""Write"" Value=""2"" />
    <Member Name=""Delete"" Value=""4"" />
  </EnumType>
  <Term Name=""Permission"" Type=""Ns.Permissions"" Nullable=""false"" />
  <EntityContainer Name=""Container"">
    <EntitySet Name=""People"" EntityType=""Ns.Person"" />
  </EntityContainer>
  <Annotations Target=""Ns.Container/People"">
    <Annotation Term=""Ns.Permission"">
      <EnumMember>Ns.Permissions/Delete</EnumMember>
    </Annotation>
  </Annotations>
</Schema>";

            IEnumerable<EdmError> errors;
            StringWriter sw = new StringWriter();
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            XmlWriter xw = XmlWriter.Create(sw, settings);
            model.TryWriteCsdl(xw, out errors);
            xw.Flush();
            xw.Close();
            var actual = sw.ToString();

            Assert.IsTrue(!errors.Any(), "No errors");
            Assert.AreEqual(expected, actual);
        }
        public void TestCommunityAlternateKeysInlineAnnotationOnEntityType()
        {
            EdmModel model = new EdmModel();

            var book = new EdmEntityType("ns", "book");
            model.AddElement(book);
            var prop1 = book.AddStructuralProperty("prop1", EdmPrimitiveTypeKind.Int32, false);
            var prop2 = book.AddStructuralProperty("prop2", EdmPrimitiveTypeKind.Int32, false);
            var prop3 = book.AddStructuralProperty("prop3", EdmPrimitiveTypeKind.Int32, false);
            var prop4 = book.AddStructuralProperty("prop4", EdmPrimitiveTypeKind.Int32, false);
            book.AddKeys(prop1);
            model.AddAlternateKeyAnnotation(book, new Dictionary<string, IEdmProperty> { { "s2", prop2 } });
            model.AddAlternateKeyAnnotation(book, new Dictionary<string, IEdmProperty> { { "s3", prop3 }, { "s4", prop4 } });

            IEnumerable<EdmError> errors;
            StringWriter sw = new StringWriter();
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            XmlWriter xw = XmlWriter.Create(sw, settings);
            model.TryWriteCsdl(xw, out errors);
            xw.Flush();
            xw.Close();
            var actual = sw.ToString();

            const string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Schema Namespace=""ns"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
  <EntityType Name=""book"">
    <Key>
      <PropertyRef Name=""prop1"" />
    </Key>
    <Property Name=""prop1"" Type=""Edm.Int32"" Nullable=""false"" />
    <Property Name=""prop2"" Type=""Edm.Int32"" Nullable=""false"" />
    <Property Name=""prop3"" Type=""Edm.Int32"" Nullable=""false"" />
    <Property Name=""prop4"" Type=""Edm.Int32"" Nullable=""false"" />
    <Annotation Term=""OData.Community.Keys.V1.AlternateKeys"">
      <Collection>
        <Record Type=""OData.Community.Keys.V1.AlternateKey"">
          <PropertyValue Property=""Key"">
            <Collection>
              <Record Type=""OData.Community.Keys.V1.PropertyRef"">
                <PropertyValue Property=""Alias"" String=""s2"" />
                <PropertyValue Property=""Name"" PropertyPath=""prop2"" />
              </Record>
            </Collection>
          </PropertyValue>
        </Record>
        <Record Type=""OData.Community.Keys.V1.AlternateKey"">
          <PropertyValue Property=""Key"">
            <Collection>
              <Record Type=""OData.Community.Keys.V1.PropertyRef"">
                <PropertyValue Property=""Alias"" String=""s3"" />
                <PropertyValue Property=""Name"" PropertyPath=""prop3"" />
              </Record>
              <Record Type=""OData.Community.Keys.V1.PropertyRef"">
                <PropertyValue Property=""Alias"" String=""s4"" />
                <PropertyValue Property=""Name"" PropertyPath=""prop4"" />
              </Record>
            </Collection>
          </PropertyValue>
        </Record>
      </Collection>
    </Annotation>
  </EntityType>
</Schema>";

            Assert.AreEqual(expected, actual);
        }
        public void TestCapabilitiesChangeTrackingInlineAnnotationOnEntityContainer()
        {
            EdmModel model = new EdmModel();

            EdmEntityType deptType = new EdmEntityType("DefaultNamespace", "Dept");
            IEdmStructuralProperty deptId = deptType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));
            deptType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(false));
            deptType.AddKeys(deptId);
            model.AddElement(deptType);

            EdmEntityType personType = new EdmEntityType("DefaultNamespace", "Person");
            EdmStructuralProperty personId = personType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));
            personType.AddKeys(personId);
            personType.AddStructuralProperty("Age", EdmCoreModel.Instance.GetInt32(true));
            personType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "MyDept", Target = deptType, TargetMultiplicity = EdmMultiplicity.One });
            deptType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "MyPeople", Target = personType, TargetMultiplicity = EdmMultiplicity.Many });
            model.AddElement(personType);

            EdmEntityContainer container = new EdmEntityContainer("DefaultNamespace", "Container");
            container.AddEntitySet("Depts", deptType);
            container.AddEntitySet("People", personType);
            model.AddElement(container);

            model.SetChangeTrackingAnnotation(container, true);

            IEnumerable<EdmError> errors;
            StringWriter sw = new StringWriter();
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            XmlWriter xw = XmlWriter.Create(sw, settings);
            model.TryWriteCsdl(xw, out errors);
            xw.Flush();
            xw.Close();
            var actual = sw.ToString();

            const string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Schema Namespace=""DefaultNamespace"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
  <EntityType Name=""Dept"">
    <Key>
      <PropertyRef Name=""Id"" />
    </Key>
    <Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false"" />
    <Property Name=""Name"" Type=""Edm.String"" Nullable=""false"" />
    <NavigationProperty Name=""MyPeople"" Type=""Collection(DefaultNamespace.Person)"" />
  </EntityType>
  <EntityType Name=""Person"">
    <Key>
      <PropertyRef Name=""Id"" />
    </Key>
    <Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false"" />
    <Property Name=""Age"" Type=""Edm.Int32"" />
    <NavigationProperty Name=""MyDept"" Type=""DefaultNamespace.Dept"" Nullable=""false"" />
  </EntityType>
  <EntityContainer Name=""Container"">
    <EntitySet Name=""Depts"" EntityType=""DefaultNamespace.Dept"" />
    <EntitySet Name=""People"" EntityType=""DefaultNamespace.Person"" />
    <Annotation Term=""Org.OData.Capabilities.V1.ChangeTracking"">
      <Record>
        <PropertyValue Property=""Supported"" Bool=""true"" />
        <PropertyValue Property=""FilterableProperties"">
          <Collection />
        </PropertyValue>
        <PropertyValue Property=""ExpandableProperties"">
          <Collection />
        </PropertyValue>
      </Record>
    </Annotation>
  </EntityContainer>
</Schema>";

            Assert.AreEqual(expected, actual);
        }
        public void TestCoreDescriptionAnnotation()
        {
            EdmModel model = new EdmModel();

            const string personTypeDescription = "this is person type.";
            const string personTypeLongDescription = "this is person type, but with a longer description.";
            const string overwritePersonDescription = "this is overwritten person type.";
            const string propertyIdDescription = "this is property Id.";
            const string structuralPropertyDescription = "this is structural property.";
            const string stringTermDescription = "this is string term.";
            const string entitySetDescription = "this is entitySet.";
            const string singletonDescription = "this is singleton.";

            EdmEntityContainer container = new EdmEntityContainer("Ns", "Container");
            var personType = new EdmEntityType("Ns", "Person");
            var propertyId = personType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));
            personType.AddKeys(propertyId);
            var structuralProperty = personType.AddStructuralProperty("Concurrency", EdmCoreModel.Instance.GetInt32(true));
            model.AddElement(personType);
            var entitySet = container.AddEntitySet("People", personType);
            var driverSet = container.AddEntitySet("Drivers", personType);

            var stringTerm = new EdmTerm("Ns", "HomeAddress", EdmCoreModel.Instance.GetString(true));
            model.AddElement(stringTerm);

            var singleton = container.AddSingleton("Boss", personType);
            model.AddElement(container);

            model.SetDescriptionAnnotation(personType, personTypeDescription);
            model.SetDescriptionAnnotation(personType, overwritePersonDescription);
            model.SetLongDescriptionAnnotation(personType, personTypeLongDescription);
            model.SetDescriptionAnnotation(structuralProperty, structuralPropertyDescription);
            model.SetDescriptionAnnotation(propertyId, propertyIdDescription);
            model.SetDescriptionAnnotation(stringTerm, stringTermDescription);
            model.SetDescriptionAnnotation(entitySet, entitySetDescription);
            model.SetDescriptionAnnotation(singleton, singletonDescription);

            Assert.AreEqual(overwritePersonDescription, model.GetDescriptionAnnotation(personType));
            Assert.AreEqual(personTypeLongDescription, model.GetLongDescriptionAnnotation(personType));
            Assert.AreEqual(structuralPropertyDescription, model.GetDescriptionAnnotation(structuralProperty));
            Assert.AreEqual(propertyIdDescription, model.GetDescriptionAnnotation(propertyId));
            Assert.AreEqual(stringTermDescription, model.GetDescriptionAnnotation(stringTerm));
            Assert.AreEqual(entitySetDescription, model.GetDescriptionAnnotation(entitySet));
            Assert.AreEqual(singletonDescription, model.GetDescriptionAnnotation(singleton));
            Assert.IsNull(model.GetDescriptionAnnotation(driverSet));

            const string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Schema Namespace=""Ns"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
  <EntityType Name=""Person"">
    <Key>
      <PropertyRef Name=""Id"" />
    </Key>
    <Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false"">
      <Annotation Term=""Org.OData.Core.V1.Description"" String=""this is property Id."" />
    </Property>
    <Property Name=""Concurrency"" Type=""Edm.Int32"">
      <Annotation Term=""Org.OData.Core.V1.Description"" String=""this is structural property."" />
    </Property>
    <Annotation Term=""Org.OData.Core.V1.Description"" String=""this is overwritten person type."" />
    <Annotation Term=""Org.OData.Core.V1.LongDescription"" String=""this is person type, but with a longer description."" />
  </EntityType>
  <Term Name=""HomeAddress"" Type=""Edm.String"">
    <Annotation Term=""Org.OData.Core.V1.Description"" String=""this is string term."" />
  </Term>
  <EntityContainer Name=""Container"">
    <EntitySet Name=""People"" EntityType=""Ns.Person"">
      <Annotation Term=""Org.OData.Core.V1.Description"" String=""this is entitySet."" />
    </EntitySet>
    <EntitySet Name=""Drivers"" EntityType=""Ns.Person"" />
    <Singleton Name=""Boss"" Type=""Ns.Person"">
      <Annotation Term=""Org.OData.Core.V1.Description"" String=""this is singleton."" />
    </Singleton>
  </EntityContainer>
</Schema>";

            IEnumerable<EdmError> errors;
            StringWriter sw = new StringWriter();
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            XmlWriter xw = XmlWriter.Create(sw, settings);
            model.TryWriteCsdl(xw, out errors);
            xw.Flush();
            xw.Close();
            var actual = sw.ToString();

            Assert.AreEqual(expected, actual);

            IEdmModel parsedModel;
            IEnumerable<EdmError> errs;
            bool parsed = CsdlReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(expected)) }, out parsedModel, out errs);
            Assert.IsTrue(parsed, "parsed");
            Assert.IsTrue(!errors.Any(), "No errors");

            Assert.AreEqual(null, parsedModel.GetDescriptionAnnotation(personType));
            Assert.AreEqual(null, parsedModel.GetDescriptionAnnotation(structuralProperty));
            Assert.AreEqual(null, parsedModel.GetDescriptionAnnotation(propertyId));
            Assert.AreEqual(null, parsedModel.GetDescriptionAnnotation(stringTerm));
            Assert.AreEqual(null, parsedModel.GetDescriptionAnnotation(entitySet));
            Assert.AreEqual(null, parsedModel.GetDescriptionAnnotation(singleton));

            var parsedPersonType = parsedModel.FindType("Ns.Person") as IEdmEntityType;
            Assert.IsNotNull(parsedPersonType);
            Assert.AreEqual(overwritePersonDescription, parsedModel.GetDescriptionAnnotation(parsedPersonType));
            Assert.AreEqual(personTypeLongDescription, parsedModel.GetLongDescriptionAnnotation(parsedPersonType));
            Assert.AreEqual(structuralPropertyDescription, parsedModel.GetDescriptionAnnotation((parsedPersonType.FindProperty("Concurrency"))));
            Assert.AreEqual(propertyIdDescription, parsedModel.GetDescriptionAnnotation(parsedPersonType.FindProperty("Id")));
            Assert.AreEqual(stringTermDescription, parsedModel.GetDescriptionAnnotation(parsedModel.FindValueTerm("Ns.HomeAddress")));
            Assert.AreEqual(entitySetDescription, parsedModel.GetDescriptionAnnotation(parsedModel.FindDeclaredEntitySet("People")));
            Assert.AreEqual(singletonDescription, parsedModel.GetDescriptionAnnotation(parsedModel.FindDeclaredSingleton("Boss")));
            Assert.IsNull(parsedModel.GetDescriptionAnnotation(parsedModel.FindDeclaredEntitySet("Drivers")));
        }
        public void TestCoreOptimisticConcurrencyControlInlineAnnotation()
        {
            EdmModel model = new EdmModel();

            EdmEntityContainer container = new EdmEntityContainer("DefaultNamespace", "Container");
            EdmEntityType personType = new EdmEntityType("DefaultNamespace", "Person");
            EdmStructuralProperty propertyId = personType.AddStructuralProperty("Id", EdmCoreModel.Instance.GetInt32(false));
            personType.AddKeys(propertyId);
            IEdmStructuralProperty concurrencyProperty = personType.AddStructuralProperty("Concurrency", EdmCoreModel.Instance.GetInt32(true));
            model.AddElement(personType);
            container.AddEntitySet("People", personType);
            model.AddElement(container);
            container.AddEntitySet("Students", personType);

            IEdmEntitySet peopleSet = model.FindDeclaredEntitySet("People");
            model.SetOptimisticConcurrencyControlAnnotation(peopleSet, new[] { concurrencyProperty });
            model.SetOptimisticConcurrencyControlAnnotation(peopleSet, new[] { concurrencyProperty });

            IEdmEntitySet studentSet = model.FindDeclaredEntitySet("Students");
            model.SetOptimisticConcurrencyControlAnnotation(studentSet, new[] { concurrencyProperty });

            IEnumerable<EdmError> errors;
            StringWriter sw = new StringWriter();
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            XmlWriter xw = XmlWriter.Create(sw, settings);
            model.TryWriteCsdl(xw, out errors);
            xw.Flush();
            xw.Close();
            var actual = sw.ToString();

            const string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>
<Schema Namespace=""DefaultNamespace"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
  <EntityType Name=""Person"">
    <Key>
      <PropertyRef Name=""Id"" />
    </Key>
    <Property Name=""Id"" Type=""Edm.Int32"" Nullable=""false"" />
    <Property Name=""Concurrency"" Type=""Edm.Int32"" />
  </EntityType>
  <EntityContainer Name=""Container"">
    <EntitySet Name=""People"" EntityType=""DefaultNamespace.Person"">
      <Annotation Term=""Org.OData.Core.V1.OptimisticConcurrencyControl"">
        <Collection>
          <PropertyPath>Concurrency</PropertyPath>
        </Collection>
      </Annotation>
    </EntitySet>
    <EntitySet Name=""Students"" EntityType=""DefaultNamespace.Person"">
      <Annotation Term=""Org.OData.Core.V1.OptimisticConcurrencyControl"">
        <Collection>
          <PropertyPath>Concurrency</PropertyPath>
        </Collection>
      </Annotation>
    </EntitySet>
  </EntityContainer>
</Schema>";

            Assert.AreEqual(expected, actual);
        }