void InitializeMetadata(ObjectContext ctx) { if (fieldDescriptors != null) { return; } fieldDescriptors = new Dictionary <string, Dictionary <string, ColumnDesc> >(); var items = ctx.MetadataWorkspace.GetItems(DataSpace.CSpace); Debug.Assert(items != null); var tables = items.Where(m => m.BuiltInTypeKind == BuiltInTypeKind.EntityType || m.BuiltInTypeKind == BuiltInTypeKind.ComplexType); foreach (StructuralType table in tables) { var fieldsMap = new Dictionary <string, ColumnDesc>(); fieldDescriptors[table.Name] = fieldsMap; ReadOnlyMetadataCollection <EdmProperty> props = null; var complexType = table as ComplexType; if (complexType != null) { props = complexType.Properties; } var entityType = table as EntityType; if (entityType != null) { props = entityType.Properties; } Debug.Assert(props != null); var fields = props.Where(p => p.DeclaringType.Name == table.Name); foreach (var field in fields) { int maxLength = 0; byte scale = 0; if (field.TypeUsage.EdmType.Name == "String") { var value = field.TypeUsage.Facets["MaxLength"].Value; if (value is Int32) { maxLength = Convert.ToInt32(value); } else { // unbounded maxLength = Int32.MaxValue; } } else if (field.TypeUsage.EdmType.Name == "Decimal") { var value = field.TypeUsage.Facets["Scale"].Value; scale = Convert.ToByte(value); } var desc = new ColumnDesc(field.Name, field.Nullable, maxLength, scale); fieldsMap[field.Name] = desc; } } }
private IEnumerable <DynamicFilterDefinition> FindFiltersForEntitySet(ReadOnlyMetadataCollection <MetadataProperty> metadataProperties, EntityContainer entityContainer) { var filterList = metadataProperties .Where(mp => mp.Name.Contains("customannotation:" + DynamicFilterConstants.ATTRIBUTE_NAME_PREFIX)) .Select(m => m.Value as DynamicFilterDefinition) .ToList(); // Note: Prior to the switch to use CSpace (which was done to allow filters on navigation properties), // we had to remove filters that exist in base EntitySets to this entity to fix issues with // Table-per-Type inheritance (issue #32). In CSpace none of that is necessary since we are working // with the actual c# models now (in CSpace) so we always have the correct filters and access to all // the inherited properties that we need. if (filterList.Any()) { // Recursively remove any filters that exist in base EntitySets to this entity. // This happens when an entity uses Table-per-Type inheritance. Filters will be added // to all derived EntitySets because of the inheritance in the C# classes. But the database // representation (the EntitySet) does not give access to inherited propeties since they // only exist in the child EntitySet. And on queries of entities involved in TPT, the // query will generate a DbScanExpression for each EntitySet - so we only want the filters // applied to the DbScanExpression to which they apply. // See issue #32. RemoveFiltersForBaseClass(filterList.First().CLRType, filterList, entityContainer); } return(filterList); }
private void GenerateFieldInfos(DbSetInfo dbSetInfo, string[] keys, EdmProperty[] edmProps) { short pkNum = 0; Array.ForEach(edmProps, (edmProp) => { Field fieldInfo = new Field() { fieldName = edmProp.Name }; if (keys.Contains(fieldInfo.fieldName)) { ++pkNum; fieldInfo.isPrimaryKey = pkNum; fieldInfo.isReadOnly = true; } bool isComputed = this.isComputed(edmProp); fieldInfo.isAutoGenerated = isAutoGenerated(edmProp); fieldInfo.isNullable = edmProp.Nullable; fieldInfo.isReadOnly = fieldInfo.isAutoGenerated; bool isArray = false; string propType = edmProp.TypeUsage.EdmType.Name; try { fieldInfo.dataType = DataTypeFromType(propType, out isArray); ReadOnlyMetadataCollection <Facet> facets = edmProp.TypeUsage.Facets; Facet maxLenFacet = facets.Where(f => f.Name == "MaxLength").FirstOrDefault(); if (maxLenFacet != null) { try { fieldInfo.maxLength = (short)Convert.ChangeType(maxLenFacet.Value, typeof(short)); } catch { } } //gess that the property is rowversion fieldInfo.fieldType = (isComputed && fieldInfo.dataType == DataType.Binary) ? FieldType.RowTimeStamp : FieldType.None; } catch (UnSupportedTypeException) { BuiltInTypeKind typeKind = edmProp.TypeUsage.EdmType.BuiltInTypeKind; if (typeKind == BuiltInTypeKind.ComplexType) { fieldInfo.dataType = DataType.None; fieldInfo.fieldType = FieldType.Object; } else { throw; } } dbSetInfo.fieldInfos.Add(fieldInfo); }); }
private bool DoPropertiesHaveDefaultNames(ReadOnlyMetadataCollection <EdmProperty> properties, ReadOnlyMetadataCollection <EdmProperty> otherEndProperties) { if (properties.Count != otherEndProperties.Count) { return(false); } return(!properties.Where((t, i) => !t.Name.EndsWith("_" + otherEndProperties[i].Name)).Any()); }
private bool DoPropertiesHaveDefaultNames(ReadOnlyMetadataCollection <EdmProperty> properties, string roleName, IReadOnlyList <EdmProperty> otherEndProperties) { if (properties == null) { throw new ArgumentNullException(nameof(properties)); } if (properties.Count != otherEndProperties.Count) { return(false); } return(!properties.Where((t, i) => !t.Name.EndsWith("_" + otherEndProperties[i].Name)).Any()); }
private IEnumerable <DynamicFilterDefinition> FindFiltersForEntitySet(ReadOnlyMetadataCollection <MetadataProperty> metadataProperties, EntityContainer entityContainer) { var filterList = metadataProperties .Where(mp => mp.Name.Contains("customannotation:" + DynamicFilterConstants.ATTRIBUTE_NAME_PREFIX)) .Select(m => m.Value as DynamicFilterDefinition) .ToList(); if (filterList.Any()) { // Recursively remove any filters that exist in base EntitySets to this entity. // This happens when an entity uses Table-per-Type inheritance. Filters will be added // to all derived EntitySets because of the inheritance in the C# classes. But the database // representation (the EntitySet) does not give access to inherited propeties since they // only exist in the child EntitySet. And on queries of entities involved in TPT, the // query will generate a DbScanExpression for each EntitySet - so we only want the filters // applied to the DbScanExpression to which they apply. // See issue #32. RemoveFiltersForBaseClass(filterList.First().CLRType, filterList, entityContainer); } return(filterList); }
private IEnumerable<DynamicFilterDefinition> FindFiltersForEntitySet(ReadOnlyMetadataCollection<MetadataProperty> metadataProperties, EntityContainer entityContainer) { var filterList = metadataProperties .Where(mp => mp.Name.Contains("customannotation:" + DynamicFilterConstants.ATTRIBUTE_NAME_PREFIX)) .Select(m => m.Value as DynamicFilterDefinition) .ToList(); if (filterList.Any()) { // Recursively remove any filters that exist in base EntitySets to this entity. // This happens when an entity uses Table-per-Type inheritance. Filters will be added // to all derived EntitySets because of the inheritance in the C# classes. But the database // representation (the EntitySet) does not give access to inherited propeties since they // only exist in the child EntitySet. And on queries of entities involved in TPT, the // query will generate a DbScanExpression for each EntitySet - so we only want the filters // applied to the DbScanExpression to which they apply. // See issue #32. RemoveFiltersForBaseClass(filterList.First().CLRType, filterList, entityContainer); } return filterList; }
private IEnumerable<DynamicFilterDefinition> FindFiltersForEntitySet(ReadOnlyMetadataCollection<MetadataProperty> metadataProperties, EntityContainer entityContainer) { var filterList = metadataProperties .Where(mp => mp.Name.Contains("customannotation:" + DynamicFilterConstants.ATTRIBUTE_NAME_PREFIX)) .Select(m => m.Value as DynamicFilterDefinition) .ToList(); // Note: Prior to the switch to use CSpace (which was done to allow filters on navigation properties), // we had to remove filters that exist in base EntitySets to this entity to fix issues with // Table-per-Type inheritance (issue #32). In CSpace none of that is necessary since we are working // with the actual c# models now (in CSpace) so we always have the correct filters and access to all // the inherited properties that we need. if (filterList.Any()) { // Recursively remove any filters that exist in base EntitySets to this entity. // This happens when an entity uses Table-per-Type inheritance. Filters will be added // to all derived EntitySets because of the inheritance in the C# classes. But the database // representation (the EntitySet) does not give access to inherited propeties since they // only exist in the child EntitySet. And on queries of entities involved in TPT, the // query will generate a DbScanExpression for each EntitySet - so we only want the filters // applied to the DbScanExpression to which they apply. // See issue #32. RemoveFiltersForBaseClass(filterList.First().CLRType, filterList, entityContainer); } return filterList; }