private static void BuildEpmInfo(Type type, ClientTypeAnnotation clientTypeAnnotation, System.Data.Services.Client.Serializers.EpmSourceTree sourceTree) { if (clientTypeAnnotation.IsEntityType) { Func <EntityPropertyMappingAttribute, bool> predicate = null; Type baseType = type.BaseType; ClientTypeAnnotation annotation = null; ClientEdmModel model = ClientEdmModel.GetModel(clientTypeAnnotation.MaxProtocolVersion); ODataEntityPropertyMappingCollection mappings = null; if ((baseType != null) && (baseType != typeof(object))) { if (((EdmStructuredType)clientTypeAnnotation.EdmType).BaseType == null) { BuildEpmInfo(baseType, clientTypeAnnotation, sourceTree); mappings = model.GetAnnotationValue <ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType); } else { annotation = model.GetClientTypeAnnotation(baseType); BuildEpmInfo(baseType, annotation, sourceTree); } } foreach (EntityPropertyMappingAttribute attribute in type.GetCustomAttributes(typeof(EntityPropertyMappingAttribute), false)) { BuildEpmInfo(attribute, type, clientTypeAnnotation, sourceTree); if (mappings == null) { mappings = new ODataEntityPropertyMappingCollection(); } mappings.Add(attribute); } if (mappings != null) { ODataEntityPropertyMappingCollection annotationValue = model.GetAnnotationValue <ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType); if (annotationValue != null) { if (predicate == null) { predicate = oldM => !mappings.Any <EntityPropertyMappingAttribute>(newM => (oldM.SourcePath == newM.SourcePath)); } foreach (EntityPropertyMappingAttribute attribute2 in annotationValue.Where <EntityPropertyMappingAttribute>(predicate).ToList <EntityPropertyMappingAttribute>()) { mappings.Add(attribute2); } } model.SetAnnotationValue <ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType, mappings); } } }
/// <summary> /// By going over EntityPropertyMappingInfoAttribute(s) defined on <paramref name="type"/> /// builds the corresponding EntityPropertyMappingInfo /// </summary> /// <param name="type">Type being looked at</param> /// <param name="clientTypeAnnotation">The ClientTypeAnnotation to refer to</param> /// <param name="sourceTree">The source tree to populate.</param> private static void BuildEpmInfo(Type type, ClientTypeAnnotation clientTypeAnnotation, System.Data.Services.Client.Serializers.EpmSourceTree sourceTree) { // EPM is only allowed on entity types. Note that we can't throw now if the EPM attribute is on a complex type since we didn't throw when we ship V2. if (clientTypeAnnotation.IsEntityType) { Type baseType = c.PlatformHelper.GetBaseType(type); ClientTypeAnnotation baseClientTypeAnnotation = null; ClientEdmModel clientEdmModel = clientTypeAnnotation.model; ODataEntityPropertyMappingCollection mappings = null; if (baseType != null && baseType != typeof(object)) { // have CLR base type if (((EdmStructuredType)clientTypeAnnotation.EdmType).BaseType == null) { // CLR base type is not an entity type - append its EPM onto the current type annotation BuildEpmInfo(baseType, clientTypeAnnotation, sourceTree); // we should not create a new mapping in this case mappings = clientEdmModel.GetAnnotationValue <ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType); } else { // CLR base type is an entity type, build EPM onto the base type annotation baseClientTypeAnnotation = clientEdmModel.GetClientTypeAnnotation(baseType); BuildEpmInfo(baseType, baseClientTypeAnnotation, sourceTree); } } foreach (EntityPropertyMappingAttribute epmAttr in type.GetCustomAttributes(typeof(EntityPropertyMappingAttribute), false)) { BuildEpmInfo(epmAttr, type, clientTypeAnnotation, sourceTree); // Add these mappings to the ODataEntityPropertyMapping class so that // ODataLib can consume them if (mappings == null) { mappings = new ODataEntityPropertyMappingCollection(); } mappings.Add(epmAttr); } if (mappings != null) { ODataEntityPropertyMappingCollection oldMappings = clientEdmModel.GetAnnotationValue <ODataEntityPropertyMappingCollection>(clientTypeAnnotation.EdmType); if (oldMappings != null) { List <EntityPropertyMappingAttribute> exclusiveMappings = oldMappings.Where(oldM => !mappings.Any(newM => oldM.SourcePath == newM.SourcePath)).ToList(); foreach (EntityPropertyMappingAttribute epmAttr in exclusiveMappings) { mappings.Add(epmAttr); } } clientEdmModel.SetAnnotationValue(clientTypeAnnotation.EdmType, mappings); } } }