Пример #1
0
    /// <summary>
    /// This method attempts to determine if the specified table has an integer
    /// primary key (i.e. "rowid").  If so, it sets the
    /// <paramref name="primaryKeyMember" /> parameter to the right
    /// <see cref="EdmMember" />; otherwise, the
    /// <paramref name="primaryKeyMember" /> parameter is set to null.
    /// </summary>
    /// <param name="table">The table to check.</param>
    /// <param name="keyMembers">
    /// The collection of key members.  An attempt is always made to set this
    /// parameter to a valid value.
    /// </param>
    /// <param name="primaryKeyMember">
    /// The <see cref="EdmMember" /> that represents the integer primary key
    /// -OR- null if no such <see cref="EdmMember" /> exists.
    /// </param>
    /// <returns>
    /// Non-zero if the specified table has an integer primary key.
    /// </returns>
    private static bool IsIntegerPrimaryKey(
        EntitySetBase table,
        out ReadOnlyMetadataCollection<EdmMember> keyMembers,
        out EdmMember primaryKeyMember
        )
    {
        keyMembers = table.ElementType.KeyMembers;

        if (keyMembers.Count == 1) /* NOTE: The "rowid" only? */
        {
            EdmMember keyMember = keyMembers[0];
            PrimitiveTypeKind typeKind;

            if (MetadataHelpers.TryGetPrimitiveTypeKind(
                    keyMember.TypeUsage, out typeKind) &&
                (typeKind == PrimitiveTypeKind.Int64))
            {
                primaryKeyMember = keyMember;
                return true;
            }
        }

        primaryKeyMember = null;
        return false;
    }
Пример #2
0
 internal ExtentPair(EntitySetBase acExtent, EntitySetBase asExtent)
 {
     cExtent = acExtent;
     sExtent = asExtent;
 }
Пример #3
0
        private string GetTableName(Type type)
        {
            EntitySetBase es = GetEntitySet(type);

            return(string.Format("[{0}].[{1}]", es.MetadataProperties["Schema"].Value, es.MetadataProperties["Table"].Value));
        }
Пример #4
0
 /// <summary>
 ///     Determines whether the given member maps to a column participating in an isnull
 ///     condition. Useful to determine if a nullability constraint violation is going to
 ///     cause roundtripping problems (e.g. if type is based on nullability of a 'non-nullable'
 ///     property of a derived entity type)
 /// </summary>
 internal bool IsNullConditionMember(EntitySetBase entitySetBase, MetadataWorkspace workspace, EdmMember member)
 {
     return(SyncContains(entitySetBase, workspace, m_isNullConditionProperties, member));
 }
Пример #5
0
 public static string GetExtentKey(EntitySetBase entitySet)
 {
     return($"{entitySet.EntityContainer.Name}.{entitySet.Name}");
 }
Пример #6
0
        // Loads and registers any function mapping translators for the given extent (and related container)
        private void InitializeFunctionMappingTranslators(EntitySetBase entitySetBase, StorageEntityContainerMapping mapping)
        {
            var requiredEnds = new KeyToListMap <AssociationSet, AssociationEndMember>(
                EqualityComparer <AssociationSet> .Default);

            // see if function mapping metadata needs to be processed
            if (!m_functionMappingTranslators.ContainsKey(entitySetBase))
            {
                // load all function mapping data from the current entity container
                foreach (StorageEntitySetMapping entitySetMapping in mapping.EntitySetMaps)
                {
                    if (0 < entitySetMapping.ModificationFunctionMappings.Count)
                    {
                        // register the function mapping
                        m_functionMappingTranslators.Add(
                            entitySetMapping.Set, ModificationFunctionMappingTranslator.CreateEntitySetTranslator(entitySetMapping));

                        // register "null" function translators for all implicitly mapped association sets
                        foreach (var end in entitySetMapping.ImplicitlyMappedAssociationSetEnds)
                        {
                            var associationSet = end.ParentAssociationSet;
                            if (!m_functionMappingTranslators.ContainsKey(associationSet))
                            {
                                m_functionMappingTranslators.Add(
                                    associationSet, ModificationFunctionMappingTranslator.CreateAssociationSetTranslator(null));
                            }

                            // Remember that the current entity set is required for all updates to the collocated
                            // relationship set. This entity set's end is opposite the target end for the mapping.
                            var oppositeEnd = MetadataHelper.GetOppositeEnd(end);
                            requiredEnds.Add(associationSet, oppositeEnd.CorrespondingAssociationEndMember);
                        }
                    }
                    else
                    {
                        // register null translator (so that we never attempt to process this extent again)
                        m_functionMappingTranslators.Add(entitySetMapping.Set, null);
                    }
                }

                foreach (StorageAssociationSetMapping associationSetMapping in mapping.RelationshipSetMaps)
                {
                    if (null != associationSetMapping.ModificationFunctionMapping)
                    {
                        var set = (AssociationSet)associationSetMapping.Set;

                        // use indexer rather than Add since the association set may already have an implicit function
                        // mapping -- this explicit function mapping takes precedence in such cases
                        m_functionMappingTranslators.Add(
                            set,
                            ModificationFunctionMappingTranslator.CreateAssociationSetTranslator(associationSetMapping));

                        // remember that we've seen a function mapping for this association set, which overrides
                        // any other behaviors for determining required/optional ends
                        requiredEnds.AddRange(set, Enumerable.Empty <AssociationEndMember>());
                    }
                    else
                    {
                        if (!m_functionMappingTranslators.ContainsKey(associationSetMapping.Set))
                        {
                            // register null translator (so that we never attempt to process this extent again)
                            m_functionMappingTranslators.Add(associationSetMapping.Set, null);
                        }
                    }
                }
            }

            // register association metadata for all association sets encountered
            foreach (var associationSet in requiredEnds.Keys)
            {
                m_associationSetMetadata.Add(
                    associationSet, new AssociationSetMetadata(
                        requiredEnds.EnumerateValues(associationSet)));
            }
        }
Пример #7
0
 /// <summary>
 ///     Returns store tables affected by modifications to a particular C-layer extent. Although this
 ///     information can be inferred from the update view, we want to avoid compiling or loading
 ///     views when not required. This information can be directly determined from mapping metadata.
 /// </summary>
 /// <param name="extent"> C-layer extent. </param>
 /// <returns> Affected store tables. </returns>
 internal Set <EntitySet> GetAffectedTables(EntitySetBase extent, MetadataWorkspace workspace)
 {
     return(SyncGetValue(extent, workspace, m_affectedTables, extent));
 }
Пример #8
0
 /// <summary>
 /// Marks the specified entity set as affected by the transaction.
 /// </summary>
 /// <param name="entitySet">The entity set.</param>
 public void AddAffectedEntitySet(EntitySetBase entitySet)
 {
     this.affectedEntitySets.Add(entitySet);
 }
 protected virtual EntitySetBase VisitEntitySet(EntitySetBase entitySet)
 {
     return(entitySet);
 }
 /// <summary>
 /// this method will be called in metadatworkspace, the signature is the same as the one in ViewDictionary
 /// </summary>
 /// <param name="workspace"></param>
 /// <param name="entity"></param>
 /// <param name="type"></param>
 /// <param name="includeSubtypes"></param>
 /// <param name="generatedView"></param>
 /// <returns></returns>
 internal bool TryGetGeneratedViewOfType(MetadataWorkspace workspace, EntitySetBase entity, EntityTypeBase type, bool includeSubtypes, out GeneratedView generatedView)
 {
     return(this.m_viewDictionary.TryGetGeneratedViewOfType(workspace, entity, type, includeSubtypes, out generatedView));
 }
Пример #11
0
 /// <summary>
 ///     Construct the new StorageSetMapping object.
 /// </summary>
 /// <param name="extent"> Extent metadata object </param>
 /// <param name="entityContainerMapping"> The EntityContainer mapping that contains this extent mapping </param>
 internal StorageSetMapping(EntitySetBase extent, StorageEntityContainerMapping entityContainerMapping)
 {
     m_entityContainerMapping = entityContainerMapping;
     m_extent       = extent;
     m_typeMappings = new List <StorageTypeMapping>();
 }
 /// <summary>
 /// Calls the view dictionary to load the view, see detailed comments in the view dictionary class.
 /// </summary>
 internal GeneratedView GetGeneratedView(EntitySetBase extent, MetadataWorkspace workspace)
 {
     return(this.m_viewDictionary.GetGeneratedView(extent, workspace, this));
 }
Пример #13
0
        /// <summary>
        /// GetAuditRecordsForChange
        /// </summary>
        /// <param name="dbEntry"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        private List <Audit> GetAuditRecordsForChange(DbEntityEntry dbEntry, int userId, bool insertSpecial = false)
        {
            var           manager = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager;
            EntitySetBase setBase = manager.GetObjectStateEntry(dbEntry.Entity).EntitySet;

            string[] keyNames = setBase.ElementType.KeyMembers.Select(k => k.Name).ToArray();
            string   keyName  = keyNames.FirstOrDefault();

            List <Audit> result = new List <Audit>();

            string tableName = string.Empty;

            tableName = ObjectContext.GetObjectType(dbEntry.Entity.GetType()).Name;

            if (dbEntry.Entity.GetType().GetProperties().SingleOrDefault(p => p.GetCustomAttributes(typeof(KeyAttribute), true).Any()) != null)
            {
                keyName = dbEntry.Entity.GetType().GetProperties().SingleOrDefault(p => p.GetCustomAttributes(typeof(KeyAttribute), true).Any()).Name;
            }

            if (dbEntry.State == System.Data.EntityState.Added || insertSpecial)
            {
                // For Inserts, just add the whole record
                // If the entity implements IDescribableEntity, use the description from Describe(), otherwise use ToString()
                foreach (string propertyName in dbEntry.CurrentValues.PropertyNames)
                {
                    result.Add(new Audit()
                    {
                        AuditID    = Guid.NewGuid(),
                        LoginID    = userId,
                        DateTime   = DateTime.Now,
                        Action     = "A",                                                                                                   // Added
                        TableName  = tableName,
                        PrimaryKey = string.IsNullOrEmpty(keyName) ? keyName : dbEntry.CurrentValues.GetValue <object>(keyName).ToString(), // Again, adjust this if you have a multi-column key
                        ColumnName = propertyName,                                                                                          // Or make it nullable, whatever you want
                        NewValue   = dbEntry.CurrentValues.GetValue <object>(propertyName) == null ? null : dbEntry.CurrentValues.GetValue <object>(propertyName).ToString(),
                        // NewValue = dbEntry.CurrentValues.ToObject().ToString(),
                        HubID = 1,
                        //TODO: fix this partion id
                        PartitionId = 0
                    }
                               );
                }
            }
            else if (dbEntry.State == System.Data.EntityState.Deleted)
            {
                foreach (string propertyName in dbEntry.OriginalValues.PropertyNames)
                {
                    result.Add(new Audit()
                    {
                        AuditID    = Guid.NewGuid(),
                        LoginID    = userId,
                        DateTime   = DateTime.Now,
                        Action     = "D", // Deleted
                        TableName  = tableName,
                        PrimaryKey = string.IsNullOrEmpty(keyName) ? keyName : dbEntry.OriginalValues.GetValue <object>(keyName).ToString(),
                        ColumnName = propertyName,
                        OldValue   = dbEntry.OriginalValues.GetValue <object>(propertyName) == null ? null : dbEntry.OriginalValues.GetValue <object>(propertyName).ToString(),
                        NewValue   = DBNull.Value.ToString(),

                        HubID = 1,
                        //TODO: fix this partion id
                        PartitionId = 0
                    }
                               );
                }

                // Same with deletes, do the whole record, and use either the description from Describe() or ToString()
            }
            else if (dbEntry.State == System.Data.EntityState.Modified)
            {
                foreach (string propertyName in dbEntry.OriginalValues.PropertyNames)
                {
                    // For updates, we only want to capture the columns that actually changed
                    if (!object.Equals(dbEntry.OriginalValues.GetValue <object>(propertyName), dbEntry.CurrentValues.GetValue <object>(propertyName)))
                    {
                        result.Add(new Audit()
                        {
                            AuditID    = Guid.NewGuid(),
                            LoginID    = userId,
                            DateTime   = DateTime.Now,
                            Action     = "M", // Modified
                            TableName  = tableName,
                            PrimaryKey = string.IsNullOrEmpty(keyName) ? keyName : dbEntry.OriginalValues.GetValue <object>(keyName).ToString(),
                            ColumnName = propertyName,
                            OldValue   = dbEntry.OriginalValues.GetValue <object>(propertyName) == null ? null : dbEntry.OriginalValues.GetValue <object>(propertyName).ToString(),
                            NewValue   = dbEntry.CurrentValues.GetValue <object>(propertyName) == null ? null : dbEntry.CurrentValues.GetValue <object>(propertyName).ToString(),
                            HubID      = 1,
                            //TODO: fix this partion id
                            PartitionId = 0
                        }
                                   );
                    }
                }
            }
            // Otherwise, don't do anything, we don't care about Unchanged or Detached entities

            return(result);
        }
        internal ExtractorMetadata(EntitySetBase entitySetBase, StructuralType type, UpdateTranslator translator)
        {
            DebugCheck.NotNull(entitySetBase);
            DebugCheck.NotNull(type);
            DebugCheck.NotNull(translator);

            m_type       = type;
            m_translator = translator;

            EntityType      entityType = null;
            Set <EdmMember> keyMembers;
            Set <EdmMember> foreignKeyMembers;

            switch (type.BuiltInTypeKind)
            {
            case BuiltInTypeKind.RowType:
                // for row types (which are actually association end key records in disguise), all members
                // are keys
                keyMembers        = new Set <EdmMember>(((RowType)type).Properties).MakeReadOnly();
                foreignKeyMembers = Set <EdmMember> .Empty;
                break;

            case BuiltInTypeKind.EntityType:
                entityType        = (EntityType)type;
                keyMembers        = new Set <EdmMember>(entityType.KeyMembers).MakeReadOnly();
                foreignKeyMembers = new Set <EdmMember>(
                    ((EntitySet)entitySetBase).ForeignKeyDependents
                    .SelectMany(fk => fk.Item2.ToProperties)).MakeReadOnly();
                break;

            default:
                keyMembers        = Set <EdmMember> .Empty;
                foreignKeyMembers = Set <EdmMember> .Empty;
                break;
            }

            var members = TypeHelpers.GetAllStructuralMembers(type);

            m_memberMap = new MemberInformation[members.Count];
            // for each member, cache expensive to compute metadata information
            for (var ordinal = 0; ordinal < members.Count; ordinal++)
            {
                var member = members[ordinal];
                // figure out flags for this member
                var flags            = PropagatorFlags.NoFlags;
                var entityKeyOrdinal = default(int?);

                if (keyMembers.Contains(member))
                {
                    flags |= PropagatorFlags.Key;
                    if (null != entityType)
                    {
                        entityKeyOrdinal = entityType.KeyMembers.IndexOf(member);
                    }
                }
                if (foreignKeyMembers.Contains(member))
                {
                    flags |= PropagatorFlags.ForeignKey;
                }

                if (MetadataHelper.GetConcurrencyMode(member)
                    == ConcurrencyMode.Fixed)
                {
                    flags |= PropagatorFlags.ConcurrencyValue;
                }

                // figure out whether this member is mapped to any server generated
                // columns in the store
                var isServerGenerated = m_translator.ViewLoader.IsServerGen(entitySetBase, m_translator.MetadataWorkspace, member);

                // figure out whether member nullability is used as a condition in mapping
                var isNullConditionMember = m_translator.ViewLoader.IsNullConditionMember(
                    entitySetBase, m_translator.MetadataWorkspace, member);

                // add information about this member
                m_memberMap[ordinal] = new MemberInformation(
                    ordinal, entityKeyOrdinal, flags, member, isServerGenerated, isNullConditionMember);
            }
        }
 public override DbMappingView GetView(EntitySetBase extent)
 {
     throw new NotImplementedException();
 }
Пример #16
0
 private ViewSimplifier(EntitySetBase viewTarget)
 {
     extent = viewTarget;
 }
Пример #17
0
        private void InitializeEntitySet(EntitySetBase entitySetBase, MetadataWorkspace workspace)
        {
            var mapping = (StorageEntityContainerMapping)m_mappingCollection.GetMap(entitySetBase.EntityContainer);

            // make sure views have been generated for this sub-graph (trigger generation of the sub-graph
            // by retrieving a view for one of its components; not actually using the view here)
            if (mapping.HasViews)
            {
                m_mappingCollection.GetGeneratedView(entitySetBase, workspace);
            }

            var affectedTables = new Set <EntitySet>();

            if (null != mapping)
            {
                var isNullConditionColumns = new Set <EdmMember>();

                // find extent in the container mapping
                StorageSetMapping setMapping;
                if (entitySetBase.BuiltInTypeKind
                    == BuiltInTypeKind.EntitySet)
                {
                    setMapping = mapping.GetEntitySetMapping(entitySetBase.Name);

                    // Check for members that have result bindings in a function mapping. If a
                    // function returns the member values, it indicates they are server-generated
                    m_serverGenProperties.Unite(GetMembersWithResultBinding((StorageEntitySetMapping)setMapping));
                }
                else if (entitySetBase.BuiltInTypeKind
                         == BuiltInTypeKind.AssociationSet)
                {
                    setMapping = mapping.GetRelationshipSetMapping(entitySetBase.Name);
                }
                else
                {
                    Debug.Fail("unexpected extent type " + entitySetBase.BuiltInTypeKind);
                    throw new NotSupportedException();
                }

                // gather interesting tables, columns and properties from mapping fragments
                foreach (var mappingFragment in GetMappingFragments(setMapping))
                {
                    affectedTables.Add(mappingFragment.TableSet);

                    // get all property mappings to figure out if anything is server generated
                    m_serverGenProperties.AddRange(FindServerGenMembers(mappingFragment));

                    // get all columns participating in is null conditions
                    isNullConditionColumns.AddRange(FindIsNullConditionColumns(mappingFragment));
                }

                if (0 < isNullConditionColumns.Count)
                {
                    // gather is null condition properties based on is null condition columns
                    foreach (var mappingFragment in GetMappingFragments(setMapping))
                    {
                        m_isNullConditionProperties.AddRange(FindPropertiesMappedToColumns(isNullConditionColumns, mappingFragment));
                    }
                }
            }

            m_affectedTables.Add(entitySetBase, affectedTables.MakeReadOnly());

            InitializeFunctionMappingTranslators(entitySetBase, mapping);

            // for association sets, initialize AssociationSetMetadata if no function has claimed ownership
            // of the association yet
            if (entitySetBase.BuiltInTypeKind
                == BuiltInTypeKind.AssociationSet)
            {
                var associationSet = (AssociationSet)entitySetBase;
                if (!m_associationSetMetadata.ContainsKey(associationSet))
                {
                    m_associationSetMetadata.Add(
                        associationSet, new AssociationSetMetadata(
                            m_affectedTables[associationSet], associationSet, workspace));
                }
            }
        }
Пример #18
0
 private static string Identity(EntitySetBase entitySet)
 {
     return(entitySet.ToString());
 }
Пример #19
0
 /// <summary>
 ///     For a given extent, returns the function mapping translator.
 /// </summary>
 /// <param name="extent"> Association set or entity set for which to retrieve a translator </param>
 /// <returns> Function translator or null if none exists for this extent </returns>
 internal ModificationFunctionMappingTranslator GetFunctionMappingTranslator(EntitySetBase extent, MetadataWorkspace workspace)
 {
     return(SyncGetValue(extent, workspace, m_functionMappingTranslators, extent));
 }
Пример #20
0
        private void TypeGeneratedEventHandler(object sender, TypeGeneratedEventArgs eventArgs)
        {
            if (!this.UseDataServiceCollection)
            {
                return;
            }

            if (eventArgs.TypeSource.BuiltInTypeKind != BuiltInTypeKind.EntityType &&
                eventArgs.TypeSource.BuiltInTypeKind != BuiltInTypeKind.ComplexType)
            {
                return;
            }

            if (eventArgs.TypeSource.BuiltInTypeKind == BuiltInTypeKind.EntityType)
            {
                // Generate EntitySetAttribute only if there is exactly one entity set associated
                // with the entity type. The DataServiceEntitySetAttribute is not generated for ComplexType(s).
                EntitySetBase entitySet = this.GetUniqueEntitySetForType((EntityType)eventArgs.TypeSource);
                if (entitySet != null)
                {
                    List <CodeAttributeDeclaration> additionalAttributes = eventArgs.AdditionalAttributes;
                    CodeAttributeDeclaration        attribute            = new CodeAttributeDeclaration(
                        new CodeTypeReference(typeof(System.Data.Services.Common.EntitySetAttribute),
                                              CodeTypeReferenceOptions.GlobalReference), new CodeAttributeArgument(new CodePrimitiveExpression(entitySet.Name)));
                    additionalAttributes.Add(attribute);
                }
            }

            //// Determine if type being generated has a base type
            if (eventArgs.BaseType != null && !String.IsNullOrEmpty(eventArgs.BaseType.BaseType))
            {
                if (this.GetSourceTypes().Where(x => x.BuiltInTypeKind == BuiltInTypeKind.EntityType).Where(x => ((EntityType)x).Name == eventArgs.BaseType.BaseType).Count() != 0)
                {
                    //// Don't generate the PropertyChanged event and OnPropertyChanged method for derived type classes
                    return;
                }
            }

            //// Add the INotifyPropertyChanged interface

            List <Type> additionalInterfaces = eventArgs.AdditionalInterfaces;

            additionalInterfaces.Add(typeof(System.ComponentModel.INotifyPropertyChanged));

            //// Add the implementation of the INotifyPropertyChanged interface

            //// Generate this code:
            ////
            //// CSharp:
            ////
            //// public event global::System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
            ////
            //// protected virtual void OnPropertyChanged(string property) {
            ////     if ((this.PropertyChanged != null)) {
            ////         this.PropertyChanged(this, new global::System.ComponentModel.PropertyChangedEventArgs(property));
            ////     }
            //// }
            ////
            //// Visual Basic:
            ////
            //// Public Event PropertyChanged As Global.System.ComponentModel.PropertyChangedEventHandler Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
            //// Protected Overridable Sub OnPropertyChanged(ByVal [property] As String)
            ////     If (Not (Me.PropertyChangedEvent) Is Nothing) Then
            ////         RaiseEvent PropertyChanged(Me, New Global.System.ComponentModel.PropertyChangedEventArgs([property]))
            ////     End If
            //// End Sub


            CodeMemberEvent propertyChangedEvent = new CodeMemberEvent();

            propertyChangedEvent.Type       = new CodeTypeReference(typeof(System.ComponentModel.PropertyChangedEventHandler), CodeTypeReferenceOptions.GlobalReference);
            propertyChangedEvent.Name       = "PropertyChanged";
            propertyChangedEvent.Attributes = MemberAttributes.Public;
            propertyChangedEvent.ImplementationTypes.Add(typeof(System.ComponentModel.INotifyPropertyChanged));

            AttributeEmitter.AddGeneratedCodeAttribute(propertyChangedEvent);

            eventArgs.AdditionalMembers.Add(propertyChangedEvent);

            CodeMemberMethod propertyChangedMethod = new CodeMemberMethod();

            propertyChangedMethod.Name = "OnPropertyChanged";
            propertyChangedMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(System.String), CodeTypeReferenceOptions.GlobalReference), "property"));
            propertyChangedMethod.ReturnType = new CodeTypeReference(typeof(void));

            AttributeEmitter.AddGeneratedCodeAttribute(propertyChangedMethod);

            propertyChangedMethod.Statements.Add(
                new CodeConditionStatement(
                    new CodeBinaryOperatorExpression(
                        new CodeEventReferenceExpression(new CodeThisReferenceExpression(), "PropertyChanged"),
                        CodeBinaryOperatorType.IdentityInequality,
                        new CodePrimitiveExpression(null)),
                    new CodeExpressionStatement(
                        new CodeDelegateInvokeExpression(
                            new CodeEventReferenceExpression(new CodeThisReferenceExpression(), "PropertyChanged"),
                            new CodeExpression[] {
                new CodeThisReferenceExpression(),
                new CodeObjectCreateExpression(new CodeTypeReference(typeof(System.ComponentModel.PropertyChangedEventArgs), CodeTypeReferenceOptions.GlobalReference), new CodeArgumentReferenceExpression("property"))
            }))));
            propertyChangedMethod.Attributes = MemberAttributes.Family;
            eventArgs.AdditionalMembers.Add(propertyChangedMethod);
        }
Пример #21
0
 /// <summary>
 ///     Determines whether the given member maps to a server-generated column in the store.
 ///     Requires: InitializeExtentInformation has been called for the extent being persisted.
 /// </summary>
 /// <param name="entitySetBase"> Entity set containing member. </param>
 /// <param name="member"> Member to lookup </param>
 /// <returns> Whether the member is server generated in some context </returns>
 internal bool IsServerGen(EntitySetBase entitySetBase, MetadataWorkspace workspace, EdmMember member)
 {
     return(SyncContains(entitySetBase, workspace, m_serverGenProperties, member));
 }
Пример #22
0
        /// <summary>
        /// Gets a view corresponding to the specified extent.
        /// </summary>
        /// <param name="extent">The extent.</param>
        /// <returns>The mapping view, or null if the extent is not associated with a mapping view.</returns>
        public override DbMappingView GetView(EntitySetBase extent)
        {
            if (extent == null)
            {
                throw new ArgumentNullException("extent");
            }

            var extentName = extent.EntityContainer.Name + "." + extent.Name;

            if (extentName == "SalesManagementDemoModelStoreContainer.AccountTypes")
            {
                return(GetView0());
            }

            if (extentName == "SalesManagementDemoModelStoreContainer.Budget")
            {
                return(GetView1());
            }

            if (extentName == "SalesManagementDemoModelStoreContainer.Departments")
            {
                return(GetView2());
            }

            if (extentName == "SalesManagementDemoModelStoreContainer.Inventory")
            {
                return(GetView3());
            }

            if (extentName == "SalesManagementDemoModelStoreContainer.Order_Details")
            {
                return(GetView4());
            }

            if (extentName == "SalesManagementDemoModelStoreContainer.Orders")
            {
                return(GetView5());
            }

            if (extentName == "SalesManagementDemoModelStoreContainer.Products")
            {
                return(GetView6());
            }

            if (extentName == "SalesManagementDemoModelStoreContainer.Roles")
            {
                return(GetView7());
            }

            if (extentName == "SalesManagementDemoModelStoreContainer.Sales")
            {
                return(GetView8());
            }

            if (extentName == "SalesManagementDemoModelStoreContainer.User_Details")
            {
                return(GetView9());
            }

            if (extentName == "SalesManagementDemoModelStoreContainer.Users")
            {
                return(GetView10());
            }

            if (extentName == "SalesManagementDemoEntities.AccountTypes")
            {
                return(GetView11());
            }

            if (extentName == "SalesManagementDemoEntities.Budgets")
            {
                return(GetView12());
            }

            if (extentName == "SalesManagementDemoEntities.Departments")
            {
                return(GetView13());
            }

            if (extentName == "SalesManagementDemoEntities.Inventories")
            {
                return(GetView14());
            }

            if (extentName == "SalesManagementDemoEntities.Order_Details")
            {
                return(GetView15());
            }

            if (extentName == "SalesManagementDemoEntities.Orders")
            {
                return(GetView16());
            }

            if (extentName == "SalesManagementDemoEntities.Products")
            {
                return(GetView17());
            }

            if (extentName == "SalesManagementDemoEntities.Roles")
            {
                return(GetView18());
            }

            if (extentName == "SalesManagementDemoEntities.Sales")
            {
                return(GetView19());
            }

            if (extentName == "SalesManagementDemoEntities.User_Details")
            {
                return(GetView20());
            }

            if (extentName == "SalesManagementDemoEntities.Users")
            {
                return(GetView21());
            }

            return(null);
        }
Пример #23
0
        /// <summary>
        ///     Entry point for Type specific generation of Query Views
        /// </summary>
        internal static ViewGenResults GenerateTypeSpecificQueryView(
            StorageEntityContainerMapping containerMapping,
            ConfigViewGenerator config,
            EntitySetBase entity,
            EntityTypeBase type,
            bool includeSubtypes,
            out bool success)
        {
            DebugCheck.NotNull(containerMapping);
            DebugCheck.NotNull(config);
            DebugCheck.NotNull(entity);
            DebugCheck.NotNull(type);
            Debug.Assert(!type.Abstract, "Can not generate OfType/OfTypeOnly query view for and abstract type");

            if (config.IsNormalTracing)
            {
                Helpers.StringTraceLine("");
                Helpers.StringTraceLine(
                    "<<<<<<<< Generating Query View for Entity [" + entity.Name + "] OfType" + (includeSubtypes ? "" : "Only") + "("
                    + type.Name + ") >>>>>>>");
            }

            if (containerMapping.GetEntitySetMapping(entity.Name).QueryView != null)
            {
                //Type-specific QV does not exist in the cache, but
                // there is a EntitySet QV. So we can't generate the view (no mapping exists for this EntitySet)
                // and we rely on Query to call us again to get the EntitySet View.
                success = false;
                return(null);
            }

            //Compute Cell Groups or get it from Memoizer
            var args   = new InputForComputingCellGroups(containerMapping, config);
            var result = containerMapping.GetCellgroups(args);

            success = result.Success;

            if (!success)
            {
                return(null);
            }

            var foreignKeyConstraints = result.ForeignKeyConstraints;
            // Get a Clone of cell groups from cache since cells are modified during viewgen, and we dont want the cached copy to change
            var cellGroups  = result.CellGroups.Select(setOfcells => new CellGroup(setOfcells.Select(cell => new Cell(cell)))).ToList();
            var cells       = result.Cells;
            var identifiers = result.Identifiers;

            var viewGenResults = new ViewGenResults();
            var tmpLog         = EnsureAllCSpaceContainerSetsAreMapped(cells, containerMapping);

            if (tmpLog.Count > 0)
            {
                viewGenResults.AddErrors(tmpLog);
                Helpers.StringTraceLine(viewGenResults.ErrorsToString());
                success = true; //atleast we tried successfully
                return(viewGenResults);
            }

            foreach (var cellGroup in cellGroups)
            {
                if (!DoesCellGroupContainEntitySet(cellGroup, entity))
                {
                    continue;
                }

                ViewGenerator viewGenerator = null;
                var           groupErrorLog = new ErrorLog();
                try
                {
                    viewGenerator = new ViewGenerator(cellGroup, config, foreignKeyConstraints, containerMapping);
                }
                catch (InternalMappingException exception)
                {
                    // All exceptions have mapping errors in them
                    Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception");
                    groupErrorLog = exception.ErrorLog;
                }

                if (groupErrorLog.Count > 0)
                {
                    break;
                }
                Debug.Assert(viewGenerator != null); //make sure there is no exception thrown that does not add error to log

                var mode = includeSubtypes ? ViewGenMode.OfTypeViews : ViewGenMode.OfTypeOnlyViews;

                groupErrorLog = viewGenerator.GenerateQueryViewForSingleExtent(viewGenResults.Views, identifiers, entity, type, mode);

                if (groupErrorLog.Count != 0)
                {
                    viewGenResults.AddErrors(groupErrorLog);
                }
            }

            success = true;
            return(viewGenResults);
        }
Пример #24
0
 internal ExtentPair(EntitySetBase left, EntitySetBase right)
 {
     this.m_left  = left;
     this.m_right = right;
 }
Пример #25
0
        private CellTreeNode ConvertUnionsToNormalizedLOJs(CellTreeNode rootNode)
        {
            // Recursively, transform the subtrees rooted at rootNode's children.
            for (var i = 0; i < rootNode.Children.Count; i++)
            {
                // Method modifies input as well.
                rootNode.Children[i] = ConvertUnionsToNormalizedLOJs(rootNode.Children[i]);
            }

            // We rewrite only LOJs.
            if (rootNode.OpType != CellTreeOpType.LOJ ||
                rootNode.Children.Count < 2)
            {
                return(rootNode);
            }

            // Create the resulting LOJ node.
            var result = new OpCellTreeNode(m_viewgenContext, rootNode.OpType);

            // Create working collection for the LOJ children.
            var children = new List <CellTreeNode>();

            // If rootNode looks something like ((V0 IJ V1) LOJ V2 LOJ V3),
            // and it turns out that there are FK associations from V2 or V3 pointing, let's say at V0,
            // then we want to rewrite the result as (V1 IJ (V0 LOJ V2 LOJ V3)).
            // If we don't do this, then plan compiler won't have a chance to eliminate LOJ V2 LOJ V3.
            // Hence, flatten the first child or rootNode if it's IJ, but remember that its parts are driving nodes for the LOJ,
            // so that we don't accidentally nest them.
            OpCellTreeNode         resultIJDriver         = null;
            HashSet <CellTreeNode> resultIJDriverChildren = null;

            if (rootNode.Children[0].OpType
                == CellTreeOpType.IJ)
            {
                // Create empty resultIJDriver node and add it as the first child (driving) into the LOJ result.
                resultIJDriver = new OpCellTreeNode(m_viewgenContext, rootNode.Children[0].OpType);
                result.Add(resultIJDriver);

                children.AddRange(rootNode.Children[0].Children);
                resultIJDriverChildren = new HashSet <CellTreeNode>(rootNode.Children[0].Children);
            }
            else
            {
                result.Add(rootNode.Children[0]);
            }

            // Flatten unions in non-driving nodes: (V0 LOJ (V1 Union V2 Union V3)) -> (V0 LOJ V1 LOJ V2 LOJ V3)
            foreach (var child in rootNode.Children.Skip(1))
            {
                var opNode = child as OpCellTreeNode;
                if (opNode != null &&
                    opNode.OpType == CellTreeOpType.Union)
                {
                    children.AddRange(opNode.Children);
                }
                else
                {
                    children.Add(child);
                }
            }

            // A dictionary that maps an extent to the nodes that are from that extent.
            // We want a ref comparer here.
            var extentMap = new KeyToListMap <EntitySet, LeafCellTreeNode>(EqualityComparer <EntitySet> .Default);

            // Note that we skip non-leaf nodes (non-leaf nodes don't have FKs) and attach them directly to the result.
            foreach (var child in children)
            {
                var leaf = child as LeafCellTreeNode;
                if (leaf != null)
                {
                    EntitySetBase extent = GetLeafNodeTable(leaf);
                    if (extent != null)
                    {
                        extentMap.Add((EntitySet)extent, leaf);
                    }
                }
                else
                {
                    if (resultIJDriverChildren != null &&
                        resultIJDriverChildren.Contains(child))
                    {
                        resultIJDriver.Add(child);
                    }
                    else
                    {
                        result.Add(child);
                    }
                }
            }

            // We only deal with simple cases - one node per extent, remove the rest from children and attach directly to result.
            var nonTrivial = extentMap.KeyValuePairs.Where(m => m.Value.Count > 1).ToArray();

            foreach (var m in nonTrivial)
            {
                extentMap.RemoveKey(m.Key);
                foreach (var n in m.Value)
                {
                    if (resultIJDriverChildren != null &&
                        resultIJDriverChildren.Contains(n))
                    {
                        resultIJDriver.Add(n);
                    }
                    else
                    {
                        result.Add(n);
                    }
                }
            }
            Debug.Assert(extentMap.KeyValuePairs.All(m => m.Value.Count == 1), "extentMap must map to single nodes only.");

            // Walk the extents in extentMap and for each extent build PK -> FK1(PK1), FK2(PK2), ... map
            // where PK is the primary key of the left extent, and FKn(PKn) is an FK of a right extent that
            // points to the PK of the left extent and is based on the PK columns of the right extent.
            // Example:
            //           table tBaseType(Id int, c1 int), PK = (tBaseType.Id)
            //           table tDerivedType1(Id int, c2 int), PK1 = (tDerivedType1.Id), FK1 = (tDerivedType1.Id -> tBaseType.Id)
            //           table tDerivedType2(Id int, c3 int), PK2 = (tDerivedType2.Id), FK2 = (tDerivedType2.Id -> tBaseType.Id)
            // Will produce:
            //           (tBaseType) -> (tDerivedType1, tDerivedType2)
            var pkFkMap = new KeyToListMap <EntitySet, EntitySet>(EqualityComparer <EntitySet> .Default);
            // Also for each extent in extentMap, build another map (extent) -> (LOJ node).
            // It will be used to construct the nesting in the next step.
            var extentLOJs = new Dictionary <EntitySet, OpCellTreeNode>(EqualityComparer <EntitySet> .Default);

            foreach (var extentInfo in extentMap.KeyValuePairs)
            {
                var principalExtent = extentInfo.Key;
                foreach (var fkExtent in GetFKOverPKDependents(principalExtent))
                {
                    // Only track fkExtents that are in extentMap.
                    ReadOnlyCollection <LeafCellTreeNode> nodes;
                    if (extentMap.TryGetListForKey(fkExtent, out nodes))
                    {
                        // Make sure that we are not adding resultIJDriverChildren as FK dependents - we do not want them to get nested.
                        if (resultIJDriverChildren == null ||
                            !resultIJDriverChildren.Contains(nodes.Single()))
                        {
                            pkFkMap.Add(principalExtent, fkExtent);
                        }
                    }
                }
                var extentLojNode = new OpCellTreeNode(m_viewgenContext, CellTreeOpType.LOJ);
                extentLojNode.Add(extentInfo.Value.Single());
                extentLOJs.Add(principalExtent, extentLojNode);
            }

            // Construct LOJ nesting inside extentLOJs based on the information in pkFkMap.
            // Also, track nested extents using nestedExtents.
            // Example:
            // We start with nestedExtents empty extentLOJs as such:
            //      tBaseType -> LOJ(BaseTypeNode)
            //      tDerivedType1 -> LOJ(DerivedType1Node)*
            //      tDerivedType2 -> LOJ(DerivedType2Node)**
            // Note that * and ** represent object references. So each time something is nested,
            // we don't clone, but nest the original LOJ. When we get to processing the extent of that LOJ,
            // we might add other children to that nested LOJ.
            // As we walk pkFkMap, we end up with this:
            //      tBaseType -> LOJ(BaseTypeNode, LOJ(DerivedType1Node)*, LOJ(DerivedType2Node)**)
            //      tDerivedType1 -> LOJ(DerivedType1Node)*
            //      tDerivedType2 -> LOJ(DerivedType2Node)**
            // nestedExtens = (tDerivedType1, tDerivedType2)
            var nestedExtents = new Dictionary <EntitySet, EntitySet>(EqualityComparer <EntitySet> .Default);

            foreach (var m in pkFkMap.KeyValuePairs)
            {
                var principalExtent = m.Key;
                foreach (var fkExtent in m.Value)
                {
                    OpCellTreeNode fkExtentLOJ;
                    if (extentLOJs.TryGetValue(fkExtent, out fkExtentLOJ)
                        &&
                        // make sure we don't nest twice and we don't create a cycle.
                        !nestedExtents.ContainsKey(fkExtent) &&
                        !CheckLOJCycle(fkExtent, principalExtent, nestedExtents))
                    {
                        extentLOJs[m.Key].Add(fkExtentLOJ);
                        nestedExtents.Add(fkExtent, principalExtent);
                    }
                }
            }

            // Now we need to grab the LOJs that have not been nested and add them to the result.
            // All LOJs that have been nested must be somewhere inside the LOJs that have not been nested,
            // so they as well end up in the result as part of the unnested ones.
            foreach (var m in extentLOJs)
            {
                if (!nestedExtents.ContainsKey(m.Key))
                {
                    // extentLOJ represents (Vx LOJ Vy LOJ(Vm LOJ Vn)) where Vx is the original node from rootNode.Children or resultIJDriverChildren.
                    var extentLOJ = m.Value;
                    if (resultIJDriverChildren != null &&
                        resultIJDriverChildren.Contains(extentLOJ.Children[0]))
                    {
                        resultIJDriver.Add(extentLOJ);
                    }
                    else
                    {
                        result.Add(extentLOJ);
                    }
                }
            }

            return(result.Flatten());
        }
        /// <summary>
        /// Gets a view corresponding to the specified extent.
        /// </summary>
        /// <param name="extent">The extent.</param>
        /// <returns>The mapping view, or null if the extent is not associated with a mapping view.</returns>
        public override DbMappingView GetView(EntitySetBase extent)
        {
            if (extent == null)
            {
                throw new ArgumentNullException("extent");
            }

            var extentName = extent.EntityContainer.Name + "." + extent.Name;

            if (extentName == "CodeFirstDatabase.Address")
            {
                return(GetView0());
            }

            if (extentName == "CodeFirstDatabase.CustomerAddress")
            {
                return(GetView1());
            }

            if (extentName == "CodeFirstDatabase.Customer")
            {
                return(GetView2());
            }

            if (extentName == "CodeFirstDatabase.SalesOrderHeader")
            {
                return(GetView3());
            }

            if (extentName == "CodeFirstDatabase.SalesOrderDetail")
            {
                return(GetView4());
            }

            if (extentName == "CodeFirstDatabase.Product")
            {
                return(GetView5());
            }

            if (extentName == "CodeFirstDatabase.ProductCategory")
            {
                return(GetView6());
            }

            if (extentName == "CodeFirstDatabase.ProductModel")
            {
                return(GetView7());
            }

            if (extentName == "CodeFirstDatabase.ProductModelProductDescription")
            {
                return(GetView8());
            }

            if (extentName == "CodeFirstDatabase.ProductDescription")
            {
                return(GetView9());
            }

            if (extentName == "AdventureWorksLt2012.Addresses")
            {
                return(GetView10());
            }

            if (extentName == "AdventureWorksLt2012.CustomerAddresses")
            {
                return(GetView11());
            }

            if (extentName == "AdventureWorksLt2012.Customers")
            {
                return(GetView12());
            }

            if (extentName == "AdventureWorksLt2012.SalesOrderHeaders")
            {
                return(GetView13());
            }

            if (extentName == "AdventureWorksLt2012.SalesOrderDetails")
            {
                return(GetView14());
            }

            if (extentName == "AdventureWorksLt2012.Products")
            {
                return(GetView15());
            }

            if (extentName == "AdventureWorksLt2012.ProductCategories")
            {
                return(GetView16());
            }

            if (extentName == "AdventureWorksLt2012.ProductModels")
            {
                return(GetView17());
            }

            if (extentName == "AdventureWorksLt2012.ProductModelProductDescriptions")
            {
                return(GetView18());
            }

            if (extentName == "AdventureWorksLt2012.ProductDescriptions")
            {
                return(GetView19());
            }

            if (extentName == "CodeFirstDatabase.vGetAllCategory")
            {
                return(GetView20());
            }

            if (extentName == "AdventureWorksLt2012.vGetAllCategories")
            {
                return(GetView21());
            }

            if (extentName == "CodeFirstDatabase.vProductAndDescription")
            {
                return(GetView22());
            }

            if (extentName == "AdventureWorksLt2012.vProductAndDescriptions")
            {
                return(GetView23());
            }

            if (extentName == "CodeFirstDatabase.vProductModelCatalogDescription")
            {
                return(GetView24());
            }

            if (extentName == "AdventureWorksLt2012.vProductModelCatalogDescriptions")
            {
                return(GetView25());
            }

            return(null);
        }
Пример #27
0
 private ViewSimplifier(MetadataWorkspace mws, EntitySetBase viewTarget)
 {
     this.metadata = mws;
     this.extent   = viewTarget;
 }
Пример #28
0
 /// <summary>
 ///     Utility method reading value from dictionary within read lock.
 /// </summary>
 private T_Value SyncGetValue <T_Key, T_Value>(
     EntitySetBase entitySetBase, MetadataWorkspace workspace, Dictionary <T_Key, T_Value> dictionary, T_Key key)
 {
     return(SyncInitializeEntitySet(entitySetBase, workspace, k => dictionary[k], key));
 }
Пример #29
0
        private string GetPrimaryKeyName(Type type)
        {
            EntitySetBase es = GetEntitySet(type);

            return(es.ElementType.KeyMembers[0].Name);
        }
Пример #30
0
 /// <summary>
 ///     Utility method checking for membership of element in set within read lock.
 /// </summary>
 private bool SyncContains <T_Element>(
     EntitySetBase entitySetBase, MetadataWorkspace workspace, Set <T_Element> set, T_Element element)
 {
     return(SyncInitializeEntitySet(entitySetBase, workspace, set.Contains, element));
 }
Пример #31
0
 public ScanExpression(string scanString, EntitySetBase target)
 {
     _scanString = scanString;
     _target = target;
 }
        private Type getEntityType(EntitySetBase setBase)
        {
            Type setBaseType;

            if (_entityTypesCache.TryGetValue(setBase, out setBaseType))
            {
                return(setBaseType);
            }

            // if it's an entity framework internal table then return null
            if (isEntityFrameworkInternalTable(setBase))
            {
                return(null);
            }

            // Get the part of the model that contains info about the actual CLR types
            var objectItemCollection = ((ObjectItemCollection)_metadata.GetItemCollection(DataSpace.OSpace));

            // Get conceptual model
            var primitiveTypeCollection = _metadata.GetItems <EntityContainer>(DataSpace.CSpace).Single();

            // Get the mapping model
            var entityPrimitiveMappingCollection =
                _metadata.GetItems <EntityContainerMapping>(DataSpace.CSSpace).Single();

            // Get the entity type from the model and find which entities this set base refers to
            var oSpace = _metadata.GetItems <EntityType>(DataSpace.OSpace);

            foreach (var entityType in oSpace)
            {
                // Get the entity set that uses this entity type
                var entitySet = primitiveTypeCollection.EntitySets
                                .SingleOrDefault(s => s.ElementType.Name == entityType.Name);

                if (entitySet == null)
                {
                    continue;
                }

                // Find the mapping between conceptual and storage model for this entity set
                var mapping = entityPrimitiveMappingCollection.EntitySetMappings
                              .Single(s => s.EntitySet == entitySet);

                // Find the storage entity set (table) that the entity is mapped to.
                // This could be mapped to multiple entities
                var isRelatedTable = mapping.EntityTypeMappings
                                     .SelectMany(typeMapping => typeMapping.Fragments)
                                     .Select(fragment => fragment.StoreEntitySet)
                                     .Select(set => set.MetadataProperties)
                                     .Any(metadataCollection => (string)metadataCollection["Table"].Value == setBase.Table);

                // is this the table we are looking for?
                if (isRelatedTable)
                {
                    var clrType = objectItemCollection.GetClrType(entityType);
                    _entityTypesCache.TryAdd(setBase, clrType);
                    return(clrType);
                }
            }

            // not found!
            return(null);
        }