private void AddDynamicPropertyReadingMap(IList <DynamicProperty> dynamicProperties, Dictionary <string, IList <DynamicPropertyDictionaryItem> > dynamicPropertyDictionaryItems) { var currentColumnIndex = MemberMaps.Count; var dynamicPropertiesPropertyInfo = ClassType.GetProperty(nameof(IHasDynamicProperties.DynamicProperties)); var dynamicPropertyReadingMap = MemberMap.CreateGeneric(ClassType, dynamicPropertiesPropertyInfo); dynamicPropertyReadingMap.Data.ReadingConvertExpression = (Expression <Func <IReaderRow, object> >)(row => dynamicProperties .Select(dynamicProperty => !string.IsNullOrEmpty(row.GetField <string>(dynamicProperty.Name)) ? new DynamicObjectProperty { Id = dynamicProperty.Id, Name = dynamicProperty.Name, DisplayNames = dynamicProperty.DisplayNames, DisplayOrder = dynamicProperty.DisplayOrder, Description = dynamicProperty.Description, IsArray = dynamicProperty.IsArray, IsDictionary = dynamicProperty.IsDictionary, IsMultilingual = dynamicProperty.IsMultilingual, IsRequired = dynamicProperty.IsRequired, ValueType = dynamicProperty.ValueType, Values = ToDynamicPropertyValues(dynamicProperty, dynamicPropertyDictionaryItems, row.GetField <string>(dynamicProperty.Name)) } : null) .Where(x => x != null) .ToList()); dynamicPropertyReadingMap.UsingExpression <ICollection <DynamicObjectProperty> >(null, null); dynamicPropertyReadingMap.Ignore(true); dynamicPropertyReadingMap.Data.IsOptional = true; dynamicPropertyReadingMap.Data.Index = currentColumnIndex + 1; MemberMaps.Add(dynamicPropertyReadingMap); }
/// <summary> /// Get the largest index for the /// members and references. /// </summary> /// <returns>The max index.</returns> public virtual int GetMaxIndex(bool isParameter = false) { if (isParameter) { return(ParameterMaps.Select(parameterMap => parameterMap.GetMaxIndex()).DefaultIfEmpty(-1).Max()); } if (MemberMaps.Count == 0 && ReferenceMaps.Count == 0) { return(-1); } var indexes = new List <int>(); if (MemberMaps.Count > 0) { indexes.Add(MemberMaps.Max(pm => pm.Data.Index)); } if (ReferenceMaps.Count > 0) { indexes.AddRange(ReferenceMaps.Select(referenceMap => referenceMap.GetMaxIndex())); } return(indexes.Max()); }
/// <summary> /// Get the largest index for the /// members and references. /// </summary> /// <returns>The max index.</returns> public virtual int GetMaxIndex() { if (ParameterMaps.Count == 0 && MemberMaps.Count == 0 && ReferenceMaps.Count == 0) { return(-1); } var indexes = new List <int>(); if (ParameterMaps.Count > 0) { indexes.AddRange(ParameterMaps.Select(parameterMap => parameterMap.GetMaxIndex())); } if (MemberMaps.Count > 0) { indexes.Add(MemberMaps.Max(pm => pm.Data.Index)); } if (ReferenceMaps.Count > 0) { indexes.AddRange(ReferenceMaps.Select(referenceMap => referenceMap.GetMaxIndex())); } return(indexes.Max()); }
internal static BoolExpression PropagateCellConstantsToWhereClause( LeftCellWrapper wrapper, BoolExpression expression, Constant constant, MemberPath member, MemberMaps memberMaps) { MemberProjectedSlot mappedSlotForSmember = wrapper.GetCSideMappedSlotForSMember(member); if (mappedSlotForSmember == null) { return(expression); } NegatedConstant negatedConstant = constant as NegatedConstant; IEnumerable <Constant> domain = memberMaps.QueryDomainMap.GetDomain(mappedSlotForSmember.MemberPath); Set <Constant> set = new Set <Constant>(Constant.EqualityComparer); if (negatedConstant != null) { set.Unite(domain); set.Difference(negatedConstant.Elements); } else { set.Add(constant); } MemberRestriction memberRestriction = (MemberRestriction) new ScalarRestriction(mappedSlotForSmember.MemberPath, (IEnumerable <Constant>)set, domain); return(BoolExpression.CreateAnd(expression, BoolExpression.CreateLiteral((BoolLiteral)memberRestriction, memberMaps.QueryDomainMap))); }
/// <summary> /// Creates an instance of the entity. /// </summary> /// <returns></returns> public object CreateInstance() { if (!_hasProtectedOrPublicConstructor) { throw new MissingMethodException("No public or protected constructor found on type " + ClassType.FullName); } if (ClassType.IsAbstract) { throw new MongoException("Unable to create an instance of an abstract class."); } EnsureCreator(); //TODO: figure out how to support custom activators... object instance = _creator.Invoke(); //initialize all default values in case something isn't specified when reader the document.) foreach (var memberMap in MemberMaps.Where(x => x.DefaultValue != null)) { memberMap.SetValue(instance, memberMap.DefaultValue); } return(instance); }
/// <summary> /// Gets the member map from alias. /// </summary> /// <param name = "propertyName">Name of the property.</param> /// <returns></returns> public PersistentMemberMap GetMemberMapFromAlias(string propertyName) { if (HasId && IdMap.Alias == propertyName) { return(IdMap); } return(MemberMaps.FirstOrDefault(memberMap => memberMap.Alias == propertyName)); }
/// <summary> /// Maps a non-member to a CSV field. This allows for writing /// data that isn't mapped to a class member. /// </summary> /// <returns>The member mapping.</returns> public virtual MemberMap <object, object> Map() { var memberMap = new MemberMap <object, object>(null); memberMap.Data.Index = GetMaxIndex() + 1; MemberMaps.Add(memberMap); return(memberMap); }
/// <summary> /// Gets the member map that corresponds to the specified member name. /// </summary> /// <param name = "memberName">Name of the member.</param> /// <returns></returns> public PersistentMemberMap GetMemberMapFromMemberName(string memberName) { if (HasId && IdMap.MemberName == memberName) { return(IdMap); } return(MemberMaps.FirstOrDefault(memberMap => memberMap.MemberName == memberName)); }
internal ViewgenContext( ViewTarget viewTarget, EntitySetBase extent, IList <Cell> extentCells, CqlIdentifiers identifiers, ConfigViewGenerator config, MemberDomainMap queryDomainMap, MemberDomainMap updateDomainMap, EntityContainerMapping entityContainerMapping) { foreach (Cell extentCell in (IEnumerable <Cell>)extentCells) { ; } this.m_extent = extent; this.m_viewTarget = viewTarget; this.m_config = config; this.m_edmItemCollection = entityContainerMapping.StorageMappingItemCollection.EdmItemCollection; this.m_entityContainerMapping = entityContainerMapping; this.m_identifiers = identifiers; updateDomainMap = updateDomainMap.MakeCopy(); MemberDomainMap domainMap = viewTarget == ViewTarget.QueryView ? queryDomainMap : updateDomainMap; this.m_memberMaps = new MemberMaps(viewTarget, MemberProjectionIndex.Create(extent, this.m_edmItemCollection), queryDomainMap, updateDomainMap); FragmentQueryKBChaseSupport kb1 = new FragmentQueryKBChaseSupport(); kb1.CreateVariableConstraints(extent, domainMap, this.m_edmItemCollection); this.m_leftFragmentQP = new FragmentQueryProcessor(kb1); this.m_rewritingCache = new Dictionary <FragmentQuery, Tile <FragmentQuery> >(FragmentQuery.GetEqualityComparer(this.m_leftFragmentQP)); if (!this.CreateLeftCellWrappers(extentCells, viewTarget)) { return; } FragmentQueryKBChaseSupport kb2 = new FragmentQueryKBChaseSupport(); MemberDomainMap memberDomainMap = viewTarget == ViewTarget.QueryView ? updateDomainMap : queryDomainMap; foreach (LeftCellWrapper cellWrapper in this.m_cellWrappers) { EntitySetBase rightExtent = cellWrapper.RightExtent; kb2.CreateVariableConstraints(rightExtent, memberDomainMap, this.m_edmItemCollection); kb2.CreateAssociationConstraints(rightExtent, memberDomainMap, this.m_edmItemCollection); } if (this.m_viewTarget == ViewTarget.UpdateView) { this.CreateConstraintsForForeignKeyAssociationsAffectingThisWrapper((FragmentQueryKB)kb2, memberDomainMap); } this.m_rightFragmentQP = new FragmentQueryProcessor(kb2); if (this.m_viewTarget == ViewTarget.QueryView) { this.CheckConcurrencyControlTokens(); } this.m_cellWrappers.Sort(LeftCellWrapper.Comparer); }
public void Initialize(IEnumerable <string> customAttributes) { var classType = typeof(Operation); var customAttributesPropertyInfo = classType.GetPropertyEx("Attributes"); foreach (var customAttribute in customAttributes) { var csvPropertyMap = MemberMap.CreateGeneric(classType, customAttributesPropertyInfo); csvPropertyMap.Name(customAttribute).TypeConverter(new CustomAttributesTypeConverter(customAttribute)); csvPropertyMap.Data.Index = GetMaxIndex() + 1; MemberMaps.Add(csvPropertyMap); } }
private void AddDynamicPropertyColumnDefinitionAndWritingMap(IList <DynamicProperty> dynamicProperties) { var currentColumnIndex = MemberMaps.Count; var dynamicPropertiesPropertyInfo = ClassType.GetProperty(nameof(IHasDynamicProperties.DynamicProperties)); // Exporting multiple csv fields from the same property (which is a collection) foreach (var dynamicProperty in dynamicProperties) { // create CsvPropertyMap manually, because this.Map(x =>...) does not allow // to export multiple entries for the same property var dynamicPropertyColumnDefinitionAndWriteMap = MemberMap.CreateGeneric(ClassType, dynamicPropertiesPropertyInfo); dynamicPropertyColumnDefinitionAndWriteMap.Name(dynamicProperty.Name); dynamicPropertyColumnDefinitionAndWriteMap.Data.IsOptional = true; dynamicPropertyColumnDefinitionAndWriteMap.Data.Index = currentColumnIndex++; // create custom converter instance which will get the required record from the collection dynamicPropertyColumnDefinitionAndWriteMap.UsingExpression <ICollection <DynamicObjectProperty> >(null, dynamicObjectProperties => { var dynamicObjectProperty = dynamicObjectProperties.FirstOrDefault(x => x.Name == dynamicProperty.Name && x.Values.Any()); var dynamicObjectPropertyValues = Array.Empty <string>(); if (dynamicObjectProperty != null) { if (dynamicObjectProperty.IsDictionary) { dynamicObjectPropertyValues = dynamicObjectProperty.Values? .Where(x => x.Value != null) .Select(x => x.Value.ToString()) .Distinct() .ToArray(); } else { dynamicObjectPropertyValues = dynamicObjectProperty.Values? .Where(x => x.Value != null) .Select(x => x.Value.ToString()) .ToArray(); } } return(string.Join(", ", dynamicObjectPropertyValues)); }); MemberMaps.Add(dynamicPropertyColumnDefinitionAndWriteMap); } }
/// <summary> /// Maps a member to a CSV field. /// </summary> /// <param name="classType">The type of the class this map is for. This may not be the same type /// as the member.DeclaringType or the current ClassType due to nested member mappings.</param> /// <param name="member">The member to map.</param> /// <param name="useExistingMap">If true, an existing map will be used if available. /// If false, a new map is created for the same member.</param> /// <returns>The member mapping.</returns> public MemberMap Map(Type classType, MemberInfo member, bool useExistingMap = true) { if (useExistingMap) { var existingMap = MemberMaps.Find(member); if (existingMap != null) { return(existingMap); } } var memberMap = MemberMap.CreateGeneric(classType, member); memberMap.Data.Index = GetMaxIndex() + 1; MemberMaps.Add(memberMap); return(memberMap); }
// effects: Given a sequence of constants that need to be propagated // to the C-side and the current boolean expression, generates a new // expression of the form "expression AND C-side Member in constants" // expression" and returns it. Each constant is propagated only if member // is projected -- if member is not projected, returns "expression" internal static BoolExpression PropagateCellConstantsToWhereClause( LeftCellWrapper wrapper, BoolExpression expression, Constant constant, MemberPath member, MemberMaps memberMaps) { var joinSlot = wrapper.GetCSideMappedSlotForSMember(member); if (joinSlot == null) { return(expression); } var negatedConstant = constant as NegatedConstant; // Look at the constants and determine if they correspond to // typeConstants or scalarConstants // This slot is being projected. We need to add a where clause element Debug.Assert(constant is ScalarConstant || constant.IsNull() || negatedConstant != null, "Invalid type of constant"); // We want the possible values for joinSlot.MemberPath which is a // C-side element -- so we use the queryDomainMap var possibleValues = memberMaps.QueryDomainMap.GetDomain(joinSlot.MemberPath); // Note: the values in constaints can be null or not null as // well (i.e., just not scalarConstants) var allowedValues = new Set <Constant>(Constant.EqualityComparer); if (negatedConstant != null) { // select all values from the c-side domain that are not in the negated set allowedValues.Unite(possibleValues); allowedValues.Difference(negatedConstant.Elements); } else { allowedValues.Add(constant); } MemberRestriction restriction = new ScalarRestriction(joinSlot.MemberPath, allowedValues, possibleValues); var result = BoolExpression.CreateAnd(expression, BoolExpression.CreateLiteral(restriction, memberMaps.QueryDomainMap)); return(result); }
private static FragmentQuery AddNullConditionOnCSideFragment( LeftCellWrapper wrapper, MemberPath member, MemberMaps memberMaps) { MemberProjectedSlot mappedSlotForSmember = wrapper.GetCSideMappedSlotForSMember(member); if (mappedSlotForSmember == null || !mappedSlotForSmember.MemberPath.IsNullable) { return((FragmentQuery)null); } BoolExpression whereClause = wrapper.RightCellQuery.WhereClause; IEnumerable <Constant> domain = memberMaps.QueryDomainMap.GetDomain(mappedSlotForSmember.MemberPath); MemberRestriction memberRestriction = (MemberRestriction) new ScalarRestriction(mappedSlotForSmember.MemberPath, (IEnumerable <Constant>) new Set <Constant>(Constant.EqualityComparer) { Constant.Null }, domain); return(FragmentQuery.Create(BoolExpression.CreateAnd(whereClause, BoolExpression.CreateLiteral((BoolLiteral)memberRestriction, memberMaps.QueryDomainMap)))); }
public string[] GetUnmappedPropertyNames() { var autoMappedProperties = GetPropertyNames(PropertyMaps); IEnumerable <string> properties; if (ConfiguredMemberList == MemberList.Destination) { properties = DestinationTypeDetails.PublicWriteAccessors .Select(p => p.Name) .Except(autoMappedProperties) .Except(PathMaps.Select(p => p.MemberPath.First.Name)); } else { var redirectedSourceMembers = MemberMaps .Where(pm => pm.IsMapped && pm.SourceMember != null && pm.SourceMember.Name != pm.DestinationName) .Select(pm => pm.SourceMember.Name); var ignoredSourceMembers = SourceMemberConfigs .Where(smc => smc.IsIgnored()) .Select(pm => pm.SourceMember.Name); properties = SourceTypeDetails.PublicReadAccessors .Select(p => p.Name) .Except(autoMappedProperties) .Except(redirectedSourceMembers) .Except(ignoredSourceMembers); } return(properties.Where(memberName => !Profile.GlobalIgnores.Any(memberName.StartsWith)).ToArray()); string GetPropertyName(PropertyMap pm) => ConfiguredMemberList == MemberList.Destination ? pm.DestinationName : pm.SourceMember != null ? pm.SourceMember.Name : pm.DestinationName; string[] GetPropertyNames(IEnumerable <PropertyMap> propertyMaps) => propertyMaps.Where(pm => pm.IsMapped).Select(GetPropertyName).ToArray(); }
protected void Init() { if (MemberMaps.IsNullOrEmpty()) { throw new CustomClassMapSetupException($"CustomClassMap must have some configurations for MemberMaps"); } foreach (var memberMap in MemberMaps) { var name = memberMap.Data.Names.FirstOrDefault(); if (name.IsEmpty()) { throw new CustomClassMapSetupException($"Cannot find a name for member map"); } if (!HeaderDefinitions.ContainsKey(name)) { throw new CustomClassMapSetupException($"Cannot find key {name} when setting up CustomClassMap"); } HeaderDefinitions[name].TypedPropertyName = memberMap.Data.Member.Name; HeaderDefinitions[name].Required = !memberMap.Data.IsOptional; } }
public CsvProductMap(CsvProductMappingConfiguration mappingCfg) { //Dynamical map scalar product fields use by manual mapping information var index = 0; foreach (var mappingItem in mappingCfg.PropertyMaps.Where(x => !string.IsNullOrEmpty(x.CsvColumnName) || !string.IsNullOrEmpty(x.CustomValue))) { var propertyInfo = typeof(CsvProduct).GetProperty(mappingItem.EntityColumnName); if (propertyInfo != null) { var newMap = MemberMap.CreateGeneric(typeof(CsvProduct), propertyInfo); newMap.Data.TypeConverterOptions.CultureInfo = CultureInfo.InvariantCulture; newMap.Data.TypeConverterOptions.NumberStyle = NumberStyles.Any; newMap.Data.TypeConverterOptions.BooleanTrueValues.AddRange(new List <string>() { "yes", "true" }); newMap.Data.TypeConverterOptions.BooleanFalseValues.AddRange(new List <string>() { "false", "no" }); newMap.Data.Index = ++index; if (!string.IsNullOrEmpty(mappingItem.CsvColumnName)) { //Map fields if mapping specified newMap.Name(mappingItem.CsvColumnName); } //And default values if it specified else if (mappingItem.CustomValue != null) { var typeConverter = TypeDescriptor.GetConverter(propertyInfo.PropertyType); newMap.Data.ReadingConvertExpression = (Expression <Func <IReaderRow, object> >)(x => typeConverter.ConvertFromString(mappingItem.CustomValue)); newMap.Default(mappingItem.CustomValue); } MemberMaps.Add(newMap); } } //Map properties if (mappingCfg.PropertyCsvColumns != null && mappingCfg.PropertyCsvColumns.Any()) { // Exporting multiple csv fields from the same property (which is a collection) foreach (var propertyCsvColumn in mappingCfg.PropertyCsvColumns) { // create CsvPropertyMap manually, because this.Map(x =>...) does not allow // to export multiple entries for the same property var propertyValuesInfo = typeof(CsvProduct).GetProperty(nameof(CsvProduct.Properties)); var csvPropertyMap = MemberMap.CreateGeneric(typeof(CsvProduct), propertyValuesInfo); csvPropertyMap.Name(propertyCsvColumn); csvPropertyMap.Data.Index = ++index; // create custom converter instance which will get the required record from the collection csvPropertyMap.UsingExpression <ICollection <Property> >(null, properties => { var property = properties.FirstOrDefault(x => x.Name == propertyCsvColumn && x.Values.Any()); var propertyValues = Array.Empty <string>(); if (property != null) { if (property.Dictionary) { propertyValues = property.Values ?.Where(x => !string.IsNullOrEmpty(x.Alias)) .Select(x => x.Alias) .Distinct() .ToArray(); } else { propertyValues = property.Values ?.Where(x => x.Value != null || x.Alias != null) .Select(x => x.Alias ?? x.Value.ToString()) .ToArray(); } } return(string.Join(mappingCfg.Delimiter, propertyValues)); }); MemberMaps.Add(csvPropertyMap); } var newPropInfo = typeof(CsvProduct).GetProperty(nameof(CsvProduct.Properties)); var newPropMap = MemberMap.CreateGeneric(typeof(CsvProduct), newPropInfo); newPropMap.Data.ReadingConvertExpression = (Expression <Func <IReaderRow, object> >)(x => mappingCfg.PropertyCsvColumns.Select(column => (Property) new CsvProperty { Name = column, Values = new List <PropertyValue>() { new PropertyValue() { PropertyName = column, Value = x.GetField <string>(column) } } }).ToList()); newPropMap.UsingExpression <ICollection <PropertyValue> >(null, null); newPropMap.Data.Index = ++index; MemberMaps.Add(newPropMap); newPropMap.Ignore(true); } //map line number var lineNumMeber = Map(m => m.LineNumber).ConvertUsing(row => row.Context.RawRow); lineNumMeber.Data.Index = ++index; lineNumMeber.Ignore(true); }
internal ViewgenContext( ViewTarget viewTarget, EntitySetBase extent, IList <Cell> extentCells, CqlIdentifiers identifiers, ConfigViewGenerator config, MemberDomainMap queryDomainMap, MemberDomainMap updateDomainMap, StorageEntityContainerMapping entityContainerMapping) { foreach (var cell in extentCells) { Debug.Assert(extent.Equals(cell.GetLeftQuery(viewTarget).Extent)); Debug.Assert(cell.CQuery.NumProjectedSlots == cell.SQuery.NumProjectedSlots); } m_extent = extent; m_viewTarget = viewTarget; m_config = config; m_edmItemCollection = entityContainerMapping.StorageMappingItemCollection.EdmItemCollection; m_entityContainerMapping = entityContainerMapping; m_identifiers = identifiers; // create a copy of updateDomainMap so generation of query views later on is not affected // it is modified in QueryRewriter.AdjustMemberDomainsForUpdateViews updateDomainMap = updateDomainMap.MakeCopy(); // Create a signature generator that handles all the // multiconstant work and generating the signatures var domainMap = viewTarget == ViewTarget.QueryView ? queryDomainMap : updateDomainMap; m_memberMaps = new MemberMaps( viewTarget, MemberProjectionIndex.Create(extent, m_edmItemCollection), queryDomainMap, updateDomainMap); // Create left fragment KB: includes constraints for the extent to be constructed var leftKB = new FragmentQueryKBChaseSupport(); leftKB.CreateVariableConstraints(extent, domainMap, m_edmItemCollection); m_leftFragmentQP = new FragmentQueryProcessor(leftKB); m_rewritingCache = new Dictionary <FragmentQuery, Tile <FragmentQuery> >( FragmentQuery.GetEqualityComparer(m_leftFragmentQP)); // Now using the signatures, create new cells such that // "extent's" query (C or S) is described in terms of multiconstants if (!CreateLeftCellWrappers(extentCells, viewTarget)) { return; } // Create right fragment KB: includes constraints for all extents and association roles of right queries var rightKB = new FragmentQueryKBChaseSupport(); var rightDomainMap = viewTarget == ViewTarget.QueryView ? updateDomainMap : queryDomainMap; foreach (var leftCellWrapper in m_cellWrappers) { var rightExtent = leftCellWrapper.RightExtent; rightKB.CreateVariableConstraints(rightExtent, rightDomainMap, m_edmItemCollection); rightKB.CreateAssociationConstraints(rightExtent, rightDomainMap, m_edmItemCollection); } if (m_viewTarget == ViewTarget.UpdateView) { CreateConstraintsForForeignKeyAssociationsAffectingThisWrapper(rightKB, rightDomainMap); } m_rightFragmentQP = new FragmentQueryProcessor(rightKB); // Check for concurrency control tokens if (m_viewTarget == ViewTarget.QueryView) { CheckConcurrencyControlTokens(); } // For backward compatibility - // order wrappers by increasing domain size, decreasing number of attributes m_cellWrappers.Sort(LeftCellWrapper.Comparer); }
/// <summary> /// Given a LeftCellWrapper for the S-side fragment and a non-nullable colum m, return a CQuery with nullability condition /// appended to Cquery of c-side member that column m is mapped to /// </summary> private static FragmentQuery AddNullConditionOnCSideFragment(LeftCellWrapper wrapper, MemberPath member, MemberMaps memberMaps) { var projectedSlot = wrapper.GetCSideMappedSlotForSMember(member); if (projectedSlot == null || !projectedSlot.MemberPath.IsNullable) //don't bother checking further fore non nullable C-side member { return(null); } var expression = wrapper.RightCellQuery.WhereClause; var possibleValues = memberMaps.QueryDomainMap.GetDomain(projectedSlot.MemberPath); var allowedValues = new Set <Constant>(Constant.EqualityComparer); allowedValues.Add(Constant.Null); //Create a condition as conjunction of originalCondition and slot IS NULL MemberRestriction restriction = new ScalarRestriction(projectedSlot.MemberPath, allowedValues, possibleValues); var resultingExpr = BoolExpression.CreateAnd(expression, BoolExpression.CreateLiteral(restriction, memberMaps.QueryDomainMap)); return(FragmentQuery.Create(resultingExpr)); }