Example #1
0
        static void RefTypeVisitRecord(IExtendedDataRecord record)
        {
            // For RefType the record contains exactly one field.
            int fieldIndex = 0;

            // If the field is flagged as DbNull, the shape of the value is undetermined.
            // An attempt to get such a value may trigger an exception.
            if (record.IsDBNull(fieldIndex) == false)
            {
                BuiltInTypeKind fieldTypeKind = record.DataRecordInfo.FieldMetadata[fieldIndex].
                                                FieldType.TypeUsage.EdmType.BuiltInTypeKind;
                //read only fields that contain PrimitiveType
                if (fieldTypeKind == BuiltInTypeKind.RefType)
                {
                    // Ref types are surfaced as EntityKey instances.
                    // The containing record sees them as atomic.
                    EntityKey key = record.GetValue(fieldIndex) as EntityKey;
                    // Get the EntitySet name.
                    Console.WriteLine("EntitySetName " + key.EntitySetName);
                    // Get the Name and the Value information of the EntityKey.
                    foreach (EntityKeyMember keyMember in key.EntityKeyValues)
                    {
                        Console.WriteLine("   Key Name: " + keyMember.Key);
                        Console.WriteLine("   Key Value: " + keyMember.Value);
                    }
                }
            }
        }
        private void SetProperties(IExtendedDataRecord record, object result, PlanEdmProperty[] properties)
        {
            DebugCheck.NotNull(record);
            DebugCheck.NotNull(result);
            DebugCheck.NotNull(properties);

            for (var i = 0; i < properties.Length; ++i)
            {
                if (null != properties[i].GetExistingComplex)
                {
                    var existing = properties[i].GetExistingComplex(result);
                    var obj      = CreateComplexRecursive(record.GetValue(properties[i].Ordinal), existing);
                    if (null == existing)
                    {
                        properties[i].ClrProperty(result, obj);
                    }
                }
                else
                {
                    properties[i].ClrProperty(
                        result,
                        ConvertDBNull(
                            record.GetValue(
                                properties[i].Ordinal)));
                }
            }
        }
        private void InitializeKeyValues(EntitySet entitySet, IExtendedDataRecord record)
        {
            int count = entitySet.ElementType.KeyMembers.Count;

            this._keyNames = entitySet.ElementType.KeyMemberNames;
            EntityType edmType = (EntityType)record.DataRecordInfo.RecordType.EdmType;

            if (count == 1)
            {
                this._singletonKeyValue = record[edmType.KeyMembers[0].Name];
                if (EntityUtil.IsNull(this._singletonKeyValue))
                {
                    throw new ArgumentException(Strings.EntityKey_NoNullsAllowedInKeyValuePairs, nameof(record));
                }
            }
            else
            {
                this._compositeKeyValues = new object[count];
                for (int index = 0; index < count; ++index)
                {
                    this._compositeKeyValues[index] = record[edmType.KeyMembers[index].Name];
                    if (EntityUtil.IsNull(this._compositeKeyValues[index]))
                    {
                        throw new ArgumentException(Strings.EntityKey_NoNullsAllowedInKeyValuePairs, nameof(record));
                    }
                }
            }
        }
        private void SetProperties(IExtendedDataRecord record, object result, PlanEdmProperty[] properties)
        {
            Debug.Assert(null != record, "null IExtendedDataRecord");
            Debug.Assert(null != result, "null object");
            Debug.Assert(null != properties, "null object");

            for (var i = 0; i < properties.Length; ++i)
            {
                if (null != properties[i].GetExistingComplex)
                {
                    var existing = properties[i].GetExistingComplex(result);
                    var obj = CreateComplexRecursive(record.GetValue(properties[i].Ordinal), existing);
                    if (null == existing)
                    {
                        properties[i].ClrProperty(result, obj);
                    }
                }
                else
                {
                    properties[i].ClrProperty(
                        result,
                        ConvertDBNull(
                            record.GetValue(
                                properties[i].Ordinal)));
                }
            }
        }
        private PropagatorResult CreateSimpleResult(
            IEntityStateEntry stateEntry,
            IExtendedDataRecord record,
            ExtractorMetadata.MemberInformation memberInformation,
            int identifier,
            bool isModified,
            int recordOrdinal,
            object value)
        {
            CurrentValueRecord record1 = record as CurrentValueRecord;
            PropagatorFlags    flags   = memberInformation.Flags;

            if (!isModified)
            {
                flags |= PropagatorFlags.Preserve;
            }
            if (-1 != identifier)
            {
                PropagatorResult owner = !memberInformation.IsServerGenerated && !memberInformation.IsForeignKeyMember || record1 == null?PropagatorResult.CreateKeyValue(flags, value, stateEntry, identifier) : PropagatorResult.CreateServerGenKeyValue(flags, value, stateEntry, identifier, recordOrdinal);

                this.m_translator.KeyManager.RegisterIdentifierOwner(owner);
                return(owner);
            }
            if ((memberInformation.IsServerGenerated || memberInformation.IsForeignKeyMember) && record1 != null)
            {
                return(PropagatorResult.CreateServerGenSimpleValue(flags, value, record1, recordOrdinal));
            }
            return(PropagatorResult.CreateSimpleValue(flags, value));
        }
Example #6
0
        static void StructuralTypeVisitRecord(IExtendedDataRecord record)
        {
            int fieldCount = record.DataRecordInfo.FieldMetadata.Count;

            for (int fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++)
            {
                Console.Write(record.GetName(fieldIndex) + ": ");

                // If the field is flagged as DbNull, the shape of the value is undetermined.
                // An attempt to get such a value may trigger an exception.
                if (record.IsDBNull(fieldIndex) == false)
                {
                    BuiltInTypeKind fieldTypeKind = record.DataRecordInfo.FieldMetadata[fieldIndex].
                                                    FieldType.TypeUsage.EdmType.BuiltInTypeKind;
                    // The EntityType, ComplexType and RowType are structural types
                    // that have members.
                    // Read only the PrimitiveType members of this structural type.
                    if (fieldTypeKind == BuiltInTypeKind.PrimitiveType)
                    {
                        // Primitive types are surfaced as plain objects.
                        Console.WriteLine(record.GetValue(fieldIndex).ToString());
                    }
                }
            }
        }
        private void SetProperties(IExtendedDataRecord record, object result, PlanEdmProperty[] properties)
        {
            Debug.Assert(null != record, "null IExtendedDataRecord");
            Debug.Assert(null != result, "null object");
            Debug.Assert(null != properties, "null object");

            for (int i = 0; i < properties.Length; ++i)
            {
                if (null != properties[i].GetExistingComplex)
                {
                    object existing = properties[i].GetExistingComplex(result);
                    object obj      = CreateComplexRecursive(record.GetValue(properties[i].Ordinal), existing);
                    if (null == existing)
                    {
                        properties[i].ClrProperty(result, obj);
                    }
                }
                else
                {
                    properties[i].ClrProperty(result,
                                              ConvertDBNull(
                                                  record.GetValue(
                                                      properties[i].Ordinal)));
                }
            }
        }
Example #8
0
        //</snippeteSQLRefTypes>

        //string esqlQuery = @"SELECT VALUE AVG(p.ListPrice) FROM AdventureWorksEntities.Products as p";
        //<snippeteSQLPrimitiveTypes>
        static void ExecutePrimitiveTypeQuery(string esqlQuery)
        {
            if (esqlQuery.Length == 0)
            {
                Console.WriteLine("The query string is empty.");
                return;
            }

            using (EntityConnection conn =
                       new EntityConnection("name=AdventureWorksEntities"))
            {
                conn.Open();

                // Create an EntityCommand.
                using (EntityCommand cmd = conn.CreateCommand())
                {
                    cmd.CommandText = esqlQuery;
                    // Execute the command.
                    using (EntityDataReader rdr =
                               cmd.ExecuteReader(CommandBehavior.SequentialAccess))
                    {
                        // Start reading results.
                        while (rdr.Read())
                        {
                            IExtendedDataRecord record = rdr as IExtendedDataRecord;
                            // For PrimitiveType
                            // the record contains exactly one field.
                            int fieldIndex = 0;
                            Console.WriteLine("Value: " + record.GetValue(fieldIndex));
                        }
                    }
                }
                conn.Close();
            }
        }
 internal EntityKey(EntitySet entitySet, IExtendedDataRecord record)
 {
     this._entitySetName       = entitySet.Name;
     this._entityContainerName = entitySet.EntityContainer.Name;
     this.InitializeKeyValues(entitySet, record);
     this._isLocked = true;
 }
            // requires: input is an IExtendedDataRecord representing an entity
            // returns: entity type for the given record
            private static EntityType GetEntityType(DbDataRecord dbDataRecord)
            {
                IExtendedDataRecord extendedRecord = dbDataRecord as IExtendedDataRecord;

                Debug.Assert(extendedRecord != null);

                Debug.Assert(BuiltInTypeKind.EntityType == extendedRecord.DataRecordInfo.RecordType.EdmType.BuiltInTypeKind);
                return((EntityType)extendedRecord.DataRecordInfo.RecordType.EdmType);
            }
        /// <summary>
        /// The constructor for the data reader, each EntityDataReader must always be associated with a EntityCommand and an underlying
        /// DbDataReader.  It is expected that EntityDataReader only has a reference to EntityCommand and doesn't assume responsibility
        /// of cleaning the command object, but it does assume responsibility of cleaning up the store data reader object.
        /// </summary>
        internal EntityDataReader(EntityCommand command, DbDataReader storeDataReader, CommandBehavior behavior)
        {
            Debug.Assert(command != null && storeDataReader != null);

            _command = command;
            _storeDataReader = storeDataReader;
            _storeExtendedDataRecord = storeDataReader as IExtendedDataRecord;
            _behavior = behavior;
        }
Example #12
0
        /// <summary>
        /// The constructor for the data reader, each EntityDataReader must always be associated with a EntityCommand and an underlying
        /// DbDataReader.  It is expected that EntityDataReader only has a reference to EntityCommand and doesn't assume responsibility
        /// of cleaning the command object, but it does assume responsibility of cleaning up the store data reader object.
        /// </summary>
        internal EntityDataReader(EntityCommand command, DbDataReader storeDataReader, CommandBehavior behavior)
            : base()
        {
            Debug.Assert(command != null && storeDataReader != null);

            this._command                 = command;
            this._storeDataReader         = storeDataReader;
            this._storeExtendedDataRecord = storeDataReader as IExtendedDataRecord;
            this._behavior                = behavior;
        }
        /// <summary>
        ///     The constructor for the data reader, each EntityDataReader must always be associated with a EntityCommand and an underlying
        ///     DbDataReader.  It is expected that EntityDataReader only has a reference to EntityCommand and doesn't assume responsibility
        ///     of cleaning the command object, but it does assume responsibility of cleaning up the store data reader object.
        /// </summary>
        internal EntityDataReader(EntityCommand command, DbDataReader storeDataReader, CommandBehavior behavior)
        {
            DebugCheck.NotNull(command);
            DebugCheck.NotNull(storeDataReader);

            _command = command;
            _storeDataReader = storeDataReader;
            _storeExtendedDataRecord = storeDataReader as IExtendedDataRecord;
            _behavior = behavior;
        }
Example #14
0
 internal EntityDataReader(
     EntityCommand command,
     DbDataReader storeDataReader,
     CommandBehavior behavior)
 {
     this._command                 = command;
     this._storeDataReader         = storeDataReader;
     this._storeExtendedDataRecord = storeDataReader as IExtendedDataRecord;
     this._behavior                = behavior;
 }
Example #15
0
        /// <summary>
        ///     The constructor for the data reader, each EntityDataReader must always be associated with a EntityCommand and an underlying
        ///     DbDataReader.  It is expected that EntityDataReader only has a reference to EntityCommand and doesn't assume responsibility
        ///     of cleaning the command object, but it does assume responsibility of cleaning up the store data reader object.
        /// </summary>
        internal EntityDataReader(EntityCommand command, DbDataReader storeDataReader, CommandBehavior behavior)
        {
            DebugCheck.NotNull(command);
            DebugCheck.NotNull(storeDataReader);

            _command                 = command;
            _storeDataReader         = storeDataReader;
            _storeExtendedDataRecord = storeDataReader as IExtendedDataRecord;
            _behavior                = behavior;
        }
Example #16
0
 public PersistedStateEntry(EntityKey ekey, DataRecordInfo recordInfo, IExtendedDataRecord origValues, object entity, string errorMessage)
 {
     _eKey           = ekey;
     _detachedEntity = entity;
     _origValues     = new Dictionary <string, object>();
     _message        = errorMessage;
     for (var i = 0; i < origValues.FieldCount; i++)
     {
         _origValues.Add(recordInfo.FieldMetadata[i].FieldType.Name, origValues[i]);
     }
     _relationships = new List <RelationshipEnds>();
 }
Example #17
0
 internal object CreateComplex(
     IExtendedDataRecord record,
     DataRecordInfo recordInfo,
     object result)
 {
     ComplexTypeMaterializer.Plan plan = this.GetPlan(recordInfo);
     if (result == null)
     {
         result = plan.ClrType();
     }
     this.SetProperties(record, result, plan.Properties);
     return(result);
 }
Example #18
0
        private PropagatorResult CreateSimpleResult(
            IEntityStateEntry stateEntry, IExtendedDataRecord record, MemberInformation memberInformation,
            int identifier, bool isModified, int recordOrdinal, object value)
        {
            var updatableRecord = record as CurrentValueRecord;

            // construct flags for the value, which is needed for complex type and simple members
            var flags = memberInformation.Flags;

            if (!isModified)
            {
                flags |= PropagatorFlags.Preserve;
            }
            if (PropagatorResult.NullIdentifier != identifier)
            {
                // construct a key member
                PropagatorResult result;
                if ((memberInformation.IsServerGenerated || memberInformation.IsForeignKeyMember) &&
                    null != updatableRecord)
                {
                    result = PropagatorResult.CreateServerGenKeyValue(flags, value, stateEntry, identifier, recordOrdinal);
                }
                else
                {
                    result = PropagatorResult.CreateKeyValue(flags, value, stateEntry, identifier);
                }

                // we register the entity as the "owner" of an identity so that back-propagation can succeed
                // (keys can only be back-propagated to entities, not association ends). It also allows us
                // to walk to the entity state entry in case of exceptions, since the state entry propagated
                // through the stack may be eliminated in a project above a join.
                m_translator.KeyManager.RegisterIdentifierOwner(result);

                return(result);
            }
            else
            {
                if ((memberInformation.IsServerGenerated || memberInformation.IsForeignKeyMember) &&
                    null != updatableRecord)
                {
                    // note: we only produce a server gen result when
                    return(PropagatorResult.CreateServerGenSimpleValue(flags, value, updatableRecord, recordOrdinal));
                }
                else
                {
                    return(PropagatorResult.CreateSimpleValue(flags, value));
                }
            }
        }
        internal virtual void SetServerGenValue(object value)
        {
            if (RecordOrdinal != NullOrdinal)
            {
                var targetRecord = Record;

                // determine if type compensation is required
                IExtendedDataRecord recordWithMetadata = targetRecord;
                var member = recordWithMetadata.DataRecordInfo.FieldMetadata[RecordOrdinal].FieldType;

                value = value ?? DBNull.Value; // records expect DBNull rather than null
                value = AlignReturnValue(value, member);
                targetRecord.SetValue(RecordOrdinal, value);
            }
        }
        internal object CreateComplex(IExtendedDataRecord record, DataRecordInfo recordInfo, object result)
        {
            Debug.Assert(null != record, "null IExtendedDataRecord");
            Debug.Assert(null != recordInfo, "null DataRecordInfo");
            Debug.Assert(null != recordInfo.RecordType, "null TypeUsage");
            Debug.Assert(null != recordInfo.RecordType.EdmType, "null EdmType");

            Debug.Assert(Helper.IsEntityType(recordInfo.RecordType.EdmType) ||
                         Helper.IsComplexType(recordInfo.RecordType.EdmType),
                         "not EntityType or ComplexType");

            Plan plan = GetPlan(record, recordInfo);
            if (null == result)
            {
                result = ((Func<object>)plan.ClrType)();
            }
            SetProperties(record, result, plan.Properties);
            return result;
        }
Example #21
0
        // <summary>
        // Converts a record to a propagator result
        // </summary>
        // <param name="stateEntry"> state manager entry containing the record </param>
        // <param name="isModified"> Indicates whether the root element is modified (i.e., whether the type has changed) </param>
        // <param name="record"> Record to convert </param>
        // <param name="useCurrentValues"> Indicates whether we are retrieving current or original values. </param>
        // <param name="translator"> Translator for session context; registers new metadata for the record type if none exists </param>
        // <param name="modifiedPropertiesBehavior"> Indicates how to determine whether a property is modified. </param>
        // <returns> Result corresponding to the given record </returns>
        internal static PropagatorResult ExtractResultFromRecord(
            IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record,
            bool useCurrentValues, UpdateTranslator translator, ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            var structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType;
            var metadata       = translator.GetExtractorMetadata(stateEntry.EntitySet, structuralType);
            var key            = stateEntry.EntityKey;

            var nestedValues = new PropagatorResult[record.FieldCount];

            for (var ordinal = 0; ordinal < nestedValues.Length; ordinal++)
            {
                nestedValues[ordinal] = metadata.RetrieveMember(
                    stateEntry, record, useCurrentValues, key,
                    ordinal, modifiedPropertiesBehavior);
            }

            return(PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified));
        }
Example #22
0
 private PropagatorResult ConvertStateEntryToPropagatorResult(
     IEntityStateEntry stateEntry,
     bool useCurrentValues,
     ModifiedPropertiesBehavior modifiedPropertiesBehavior)
 {
     try
     {
         IExtendedDataRecord record = useCurrentValues ? (IExtendedDataRecord)stateEntry.CurrentValues : (IExtendedDataRecord)stateEntry.OriginalValues;
         bool isModified            = false;
         return(ExtractorMetadata.ExtractResultFromRecord(stateEntry, isModified, record, useCurrentValues, this.m_updateTranslator, modifiedPropertiesBehavior));
     }
     catch (Exception ex)
     {
         if (ex.RequiresContext())
         {
             throw EntityUtil.Update(Strings.Update_ErrorLoadingRecord, ex, stateEntry);
         }
         throw;
     }
 }
        internal object CreateComplex(IExtendedDataRecord record, DataRecordInfo recordInfo, object result)
        {
            Debug.Assert(null != record, "null IExtendedDataRecord");
            Debug.Assert(null != recordInfo, "null DataRecordInfo");
            Debug.Assert(null != recordInfo.RecordType, "null TypeUsage");
            Debug.Assert(null != recordInfo.RecordType.EdmType, "null EdmType");

            Debug.Assert(Helper.IsEntityType(recordInfo.RecordType.EdmType) ||
                         Helper.IsComplexType(recordInfo.RecordType.EdmType),
                         "not EntityType or ComplexType");

            Plan plan = GetPlan(record, recordInfo);

            if (null == result)
            {
                result = ((Func <object>)plan.ClrType)();
            }
            SetProperties(record, result, plan.Properties);
            return(result);
        }
        internal object CreateComplex(IExtendedDataRecord record, DataRecordInfo recordInfo, object result)
        {
            DebugCheck.NotNull(record);
            DebugCheck.NotNull(recordInfo);
            DebugCheck.NotNull(recordInfo.RecordType);
            DebugCheck.NotNull(recordInfo.RecordType.EdmType);

            Debug.Assert(
                Helper.IsEntityType(recordInfo.RecordType.EdmType) ||
                Helper.IsComplexType(recordInfo.RecordType.EdmType),
                "not EntityType or ComplexType");

            var plan = GetPlan(recordInfo);
            if (null == result)
            {
                result = plan.ClrType();
            }
            SetProperties(record, result, plan.Properties);
            return result;
        }
        internal object CreateComplex(IExtendedDataRecord record, DataRecordInfo recordInfo, object result)
        {
            DebugCheck.NotNull(record);
            DebugCheck.NotNull(recordInfo);
            DebugCheck.NotNull(recordInfo.RecordType);
            DebugCheck.NotNull(recordInfo.RecordType.EdmType);

            Debug.Assert(
                Helper.IsEntityType(recordInfo.RecordType.EdmType) ||
                Helper.IsComplexType(recordInfo.RecordType.EdmType),
                "not EntityType or ComplexType");

            var plan = GetPlan(recordInfo);

            if (null == result)
            {
                result = plan.ClrType();
            }
            SetProperties(record, result, plan.Properties);
            return(result);
        }
        private PropagatorResult ConvertStateEntryToPropagatorResult(IEntityStateEntry stateEntry, bool useCurrentValues, ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            try
            {
                EntityUtil.CheckArgumentNull(stateEntry, "stateEntry");
                IExtendedDataRecord record = useCurrentValues
                    ? EntityUtil.CheckArgumentNull(stateEntry.CurrentValues as IExtendedDataRecord, "stateEntry.CurrentValues")
                    : EntityUtil.CheckArgumentNull(stateEntry.OriginalValues as IExtendedDataRecord, "stateEntry.OriginalValues");

                bool isModified = false; // the root of the state entry is unchanged because the type is static
                return(ExtractorMetadata.ExtractResultFromRecord(stateEntry, isModified, record, useCurrentValues, m_updateTranslator, modifiedPropertiesBehavior));
            }
            catch (Exception e)
            {
                if (UpdateTranslator.RequiresContext(e))
                {
                    throw EntityUtil.Update(Strings.Update_ErrorLoadingRecord, e, stateEntry);
                }
                throw;
            }
        }
        private Plan GetPlan(IExtendedDataRecord record, DataRecordInfo recordInfo)
        {
            Debug.Assert(null != record, "null IExtendedDataRecord");
            Debug.Assert(null != recordInfo, "null DataRecordInfo");
            Debug.Assert(null != recordInfo.RecordType, "null TypeUsage");

            Plan[] plans = _lastPlans ?? (_lastPlans = new Plan[MaxPlanCount]);

            // find an existing plan in circular buffer
            int index = _lastPlanIndex - 1;

            for (int i = 0; i < MaxPlanCount; ++i)
            {
                index = (index + 1) % MaxPlanCount;
                if (null == plans[index])
                {
                    break;
                }
                if (plans[index].Key == recordInfo.RecordType)
                {
                    _lastPlanIndex = index;
                    return(plans[index]);
                }
            }
            Debug.Assert(0 <= index, "negative index");
            Debug.Assert(index != _lastPlanIndex || (null == plans[index]), "index wrapped around");

            // create a new plan
            ObjectTypeMapping mapping = System.Data.Common.Internal.Materialization.Util.GetObjectMapping(recordInfo.RecordType.EdmType, _workspace);

            Debug.Assert(null != mapping, "null ObjectTypeMapping");

            Debug.Assert(Helper.IsComplexType(recordInfo.RecordType.EdmType),
                         "IExtendedDataRecord is not ComplexType");

            _lastPlanIndex = index;
            plans[index]   = new Plan(recordInfo.RecordType, mapping, recordInfo.FieldMetadata);
            return(plans[index]);
        }
Example #28
0
 private void SetProperties(
     IExtendedDataRecord record,
     object result,
     ComplexTypeMaterializer.PlanEdmProperty[] properties)
 {
     for (int index = 0; index < properties.Length; ++index)
     {
         if (properties[index].GetExistingComplex != null)
         {
             object existing         = properties[index].GetExistingComplex(result);
             object complexRecursive = this.CreateComplexRecursive(record.GetValue(properties[index].Ordinal), existing);
             if (existing == null)
             {
                 properties[index].ClrProperty(result, complexRecursive);
             }
         }
         else
         {
             properties[index].ClrProperty(result, ComplexTypeMaterializer.ConvertDBNull(record.GetValue(properties[index].Ordinal)));
         }
     }
 }
            /// <summary>
            /// Add a relationship to be tracked by the validator.
            /// </summary>
            /// <param name="associationSet">Relationship set to which the given record belongs.</param>
            /// <param name="record">Relationship record. Must conform to the type of the relationship set.</param>
            /// <param name="stateEntry">State entry for the relationship being tracked</param>
            internal void RegisterAssociation(AssociationSet associationSet, IExtendedDataRecord record, IEntityStateEntry stateEntry)
            {
                EntityUtil.CheckArgumentNull(associationSet, "relationshipSet");
                EntityUtil.CheckArgumentNull(record, "record");
                EntityUtil.CheckArgumentNull(stateEntry, "stateEntry");

                Debug.Assert(associationSet.ElementType.Equals(record.DataRecordInfo.RecordType.EdmType));

                // retrieve the ends of the relationship
                Dictionary <string, EntityKey> endNameToKeyMap = new Dictionary <string, EntityKey>(
                    StringComparer.Ordinal);

                foreach (FieldMetadata field in record.DataRecordInfo.FieldMetadata)
                {
                    string    endName   = field.FieldType.Name;
                    EntityKey entityKey = (EntityKey)record.GetValue(field.Ordinal);
                    endNameToKeyMap.Add(endName, entityKey);
                }

                // register each unidirectional relationship subpart in the relationship instance
                var ends = associationSet.AssociationSetEnds;

                foreach (var fromEnd in ends)
                {
                    foreach (var toEnd in ends)
                    {
                        // end to itself does not describe an interesting relationship subpart
                        if (object.ReferenceEquals(toEnd.CorrespondingAssociationEndMember, fromEnd.CorrespondingAssociationEndMember))
                        {
                            continue;
                        }

                        EntityKey toEntityKey = endNameToKeyMap[toEnd.CorrespondingAssociationEndMember.Name];
                        DirectionalRelationship relationship = new DirectionalRelationship(toEntityKey, fromEnd.CorrespondingAssociationEndMember,
                                                                                           toEnd.CorrespondingAssociationEndMember, associationSet, stateEntry);
                        AddExistingRelationship(relationship);
                    }
                }
            }
        private void ValidateRecord(EntitySetBase extent, IExtendedDataRecord record, IEntityStateEntry entry)
        {
            Debug.Assert(null != extent, "must be verified by caller");

            DataRecordInfo recordInfo;
            if ((null == record) ||
                (null == (recordInfo = record.DataRecordInfo)) ||
                (null == recordInfo.RecordType))
            {
                throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.InvalidStateEntry, 2);
            }

            VerifyExtent(MetadataWorkspace, extent);

            // additional validation happens lazily as values are loaded from the record
        }
 public PersistedStateEntry(EntityKey ekey,
                            System.Data.Common.DataRecordInfo recordInfo,
                            IExtendedDataRecord origValues,
                            object entity)
 {
 }
Example #32
0
        // <summary>
        // Requires: record must have correct type for this metadata instance.
        // Populates a new <see cref="PropagatorResult" /> object representing a member of a record matching the
        // type of this extractor. Given a record and a member, this method wraps the value of the member
        // in a PropagatorResult. This operation can be performed efficiently by this class, which knows
        // important stuff about the type being extracted.
        // </summary>
        // <param name="stateEntry"> state manager entry containing value (used for error reporting) </param>
        // <param name="record"> Record containing value (used to find the actual value) </param>
        // <param name="useCurrentValues"> Indicates whether we are reading current or original values. </param>
        // <param name="key"> Entity key for the state entry. Must be set for entity records. </param>
        // <param name="ordinal"> Ordinal of Member for which to retrieve a value. </param>
        // <param name="modifiedPropertiesBehavior"> Indicates how to determine whether a property is modified. </param>
        // <returns> Propagator result describing this member value. </returns>
        internal PropagatorResult RetrieveMember(
            IEntityStateEntry stateEntry, IExtendedDataRecord record, bool useCurrentValues,
            EntityKey key, int ordinal, ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            var memberInformation = m_memberMap[ordinal];

            // get identifier value
            int identifier;

            if (memberInformation.IsKeyMember)
            {
                // retrieve identifier for this key member
                Debug.Assert(
                    null != (object)key, "entities must have keys, and only entity members are marked IsKeyMember by " +
                    "the metadata wrapper");
                var keyOrdinal = memberInformation.EntityKeyOrdinal.Value;
                identifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(key, keyOrdinal, ((EntityType)m_type).KeyMembers.Count);
            }
            else if (memberInformation.IsForeignKeyMember)
            {
                identifier = m_translator.KeyManager.GetKeyIdentifierForMember(key, record.GetName(ordinal), useCurrentValues);
            }
            else
            {
                identifier = PropagatorResult.NullIdentifier;
            }

            // determine if the member is modified
            var isModified = modifiedPropertiesBehavior == ModifiedPropertiesBehavior.AllModified ||
                             (modifiedPropertiesBehavior == ModifiedPropertiesBehavior.SomeModified &&
                              stateEntry.ModifiedProperties != null &&
                              stateEntry.ModifiedProperties[memberInformation.Ordinal]);

            // determine member value
            Debug.Assert(record.GetName(ordinal) == memberInformation.Member.Name, "expect record to present properties in metadata order");
            if (memberInformation.CheckIsNotNull &&
                record.IsDBNull(ordinal))
            {
                throw EntityUtil.Update(Strings.Update_NullValue(record.GetName(ordinal)), null, stateEntry);
            }
            var value = record.GetValue(ordinal);

            // determine what kind of member this is

            // entityKey (association end)
            var entityKey = value as EntityKey;

            if (null != (object)entityKey)
            {
                return(CreateEntityKeyResult(stateEntry, entityKey));
            }

            // record (nested complex type)
            var nestedRecord = value as IExtendedDataRecord;

            if (null != nestedRecord)
            {
                // for structural types, we track whether the entire complex type value is modified or not
                var nestedModifiedPropertiesBehavior = isModified
                                                           ? ModifiedPropertiesBehavior.AllModified
                                                           : ModifiedPropertiesBehavior.NoneModified;
                var translator = m_translator;

                return(ExtractResultFromRecord(
                           stateEntry, isModified, nestedRecord, useCurrentValues, translator, nestedModifiedPropertiesBehavior));
            }

            // simple value (column/property value)
            return(CreateSimpleResult(stateEntry, record, memberInformation, identifier, isModified, ordinal, value));
        }
 private object CreateComplexRecursive(IExtendedDataRecord record, object existing)
 {
     return CreateComplex(record, record.DataRecordInfo, existing);
 }
        static int Main(string[] args)
        {
            try
            {
                Console.WriteLine($"Profiler attached: {Instrumentation.ProfilerAttached}");

                using (var ctx = new SchoolDbContextEntities())
                {
                    // create database if missing
                    ctx.Database.CreateIfNotExists();

                    var student = new Student()
                    {
                        StudentName = "Bill", Age = 12
                    };

                    ctx.Students.Add(student);
                    ctx.SaveChanges();
                }

                // Specify the provider name, server and database.
                string providerName = "System.Data.SqlClient";
                string serverName   = @"(localdb)\MSSQLLocalDB";
                string databaseName = "SchoolDbContext";

                // Initialize the connection string builder for the
                // underlying provider.
                SqlConnectionStringBuilder sqlBuilder =
                    new SqlConnectionStringBuilder();

                // Set the properties for the data source.
                sqlBuilder.DataSource         = serverName;
                sqlBuilder.InitialCatalog     = databaseName;
                sqlBuilder.IntegratedSecurity = true;

                // Build the SqlConnection connection string.
                string providerString = sqlBuilder.ToString();

                // Initialize the EntityConnectionStringBuilder.
                EntityConnectionStringBuilder entityBuilder =
                    new EntityConnectionStringBuilder();

                //Set the provider name.
                entityBuilder.Provider = providerName;

                // Set the provider-specific connection string.
                entityBuilder.ProviderConnectionString = providerString;

                // Set the Metadata location.
                entityBuilder.Metadata = @"res://*/SchoolModel.csdl|
                            res://*/SchoolModel.ssdl|
                            res://*/SchoolModel.msl";
                Console.WriteLine(entityBuilder.ToString());

                using (EntityConnection conn =
                           new EntityConnection(entityBuilder.ToString()))
                {
                    conn.Open();

                    using (EntityCommand cmd = conn.CreateCommand())
                    {
                        Console.WriteLine("Creating an EntityCommand with this EntityConnection.");
                        cmd.CommandText = "SELECT VALUE AVG(s.Age) FROM SchoolDbContextEntities.Students as s";
                        // Execute the command.
                        using (EntityDataReader rdr =
                                   cmd.ExecuteReader(CommandBehavior.SequentialAccess))
                        {
                            // Start reading results.
                            while (rdr.Read())
                            {
                                IExtendedDataRecord record = rdr as IExtendedDataRecord;
                                // For PrimitiveType
                                // the record contains exactly one field.
                                int fieldIndex = 0;
                                Console.WriteLine("Value: " + record.GetValue(fieldIndex));
                            }
                        }

                        conn.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
                return((int)ExitCode.UnknownError);
            }

            return((int)ExitCode.Success);
        }
 private object CreateComplexRecursive(IExtendedDataRecord record, object existing)
 {
     return(CreateComplex(record, record.DataRecordInfo, existing));
 }
        internal PropagatorResult RetrieveMember(
            IEntityStateEntry stateEntry,
            IExtendedDataRecord record,
            bool useCurrentValues,
            EntityKey key,
            int ordinal,
            ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            ExtractorMetadata.MemberInformation member = this.m_memberMap[ordinal];
            int identifier;

            if (member.IsKeyMember)
            {
                int memberOffset = member.EntityKeyOrdinal.Value;
                identifier = this.m_translator.KeyManager.GetKeyIdentifierForMemberOffset(key, memberOffset, ((EntityTypeBase)this.m_type).KeyMembers.Count);
            }
            else
            {
                identifier = !member.IsForeignKeyMember ? -1 : this.m_translator.KeyManager.GetKeyIdentifierForMember(key, record.GetName(ordinal), useCurrentValues);
            }
            int num;

            switch (modifiedPropertiesBehavior)
            {
            case ModifiedPropertiesBehavior.AllModified:
                num = 1;
                break;

            case ModifiedPropertiesBehavior.SomeModified:
                if (stateEntry.ModifiedProperties != null)
                {
                    num = stateEntry.ModifiedProperties[member.Ordinal] ? 1 : 0;
                    break;
                }
                goto default;

            default:
                num = 0;
                break;
            }
            bool isModified = num != 0;

            if (member.CheckIsNotNull && record.IsDBNull(ordinal))
            {
                throw EntityUtil.Update(Strings.Update_NullValue((object)record.GetName(ordinal)), (Exception)null, stateEntry);
            }
            object    obj       = record.GetValue(ordinal);
            EntityKey entityKey = obj as EntityKey;

            if ((object)entityKey != null)
            {
                return(this.CreateEntityKeyResult(stateEntry, entityKey));
            }
            IExtendedDataRecord record1 = obj as IExtendedDataRecord;

            if (record1 == null)
            {
                return(this.CreateSimpleResult(stateEntry, record, member, identifier, isModified, ordinal, obj));
            }
            ModifiedPropertiesBehavior modifiedPropertiesBehavior1 = isModified ? ModifiedPropertiesBehavior.AllModified : ModifiedPropertiesBehavior.NoneModified;
            UpdateTranslator           translator = this.m_translator;

            return(ExtractorMetadata.ExtractResultFromRecord(stateEntry, isModified, record1, useCurrentValues, translator, modifiedPropertiesBehavior1));
        }
        private Plan GetPlan(IExtendedDataRecord record, DataRecordInfo recordInfo)
        {
            Debug.Assert(null != record, "null IExtendedDataRecord");
            Debug.Assert(null != recordInfo, "null DataRecordInfo");
            Debug.Assert(null != recordInfo.RecordType, "null TypeUsage");

            Plan[] plans = _lastPlans ?? (_lastPlans = new Plan[MaxPlanCount]);

            // find an existing plan in circular buffer
            int index = _lastPlanIndex - 1;
            for (int i = 0; i < MaxPlanCount; ++i)
            {
                index = (index + 1) % MaxPlanCount;
                if (null == plans[index])
                {
                    break;
                }
                if (plans[index].Key == recordInfo.RecordType)
                {
                    _lastPlanIndex = index;
                    return plans[index];
                }
            }
            Debug.Assert(0 <= index, "negative index");
            Debug.Assert(index != _lastPlanIndex || (null == plans[index]), "index wrapped around");

            // create a new plan
            ObjectTypeMapping mapping = System.Data.Common.Internal.Materialization.Util.GetObjectMapping(recordInfo.RecordType.EdmType, _workspace);
            Debug.Assert(null != mapping, "null ObjectTypeMapping");

            Debug.Assert(Helper.IsComplexType(recordInfo.RecordType.EdmType),
                         "IExtendedDataRecord is not ComplexType");

            _lastPlanIndex = index;
            plans[index] = new Plan(recordInfo.RecordType, mapping, recordInfo.FieldMetadata);
            return plans[index];
        }
Example #38
0
        static int Main(string[] args)
        {
            try
            {
                using (var ctx = new SchoolDbContextEntities())
                {
                    // create database if missing
                    ctx.Database.CreateIfNotExists();

                    var student = new Student()
                    {
                        StudentName = "Bill", Age = 12
                    };

                    ctx.Students.Add(student);

                    ctx.SaveChanges();

                    // Call ObjectContext.ExecuteStoreQuery which invokes the bad behavior
                    // where a branch jumps directly to the method call instruction, which
                    // throws an InvalidProgramException if we incorrectly load our custom
                    // method arguments BEFORE the original method call instruction.
                    var objContext = (ctx as IObjectContextAdapter).ObjectContext;
                    if (objContext != null)
                    {
                        SqlParameter paramName = new SqlParameter("name", "Bill");
                        var          results   = objContext.ExecuteStoreQuery <Student>("SELECT * FROM dbo.Students WHERE StudentName = @name", new ExecutionOptions(MergeOption.AppendOnly), paramName);
                        foreach (var result in results)
                        {
                            Console.WriteLine($"ExecuteStoreQuery<Student> result: StudentName={result.StudentName},Age={result.Age}");
                        }
                    }
                }

                // Specify the provider name, server and database.
                string providerName = "System.Data.SqlClient";
                string serverName   = @"(localdb)\MSSQLLocalDB";
                string databaseName = "SchoolDbContext";

                // Initialize the connection string builder for the
                // underlying provider.
                SqlConnectionStringBuilder sqlBuilder =
                    new SqlConnectionStringBuilder();

                // Set the properties for the data source.
                sqlBuilder.DataSource         = serverName;
                sqlBuilder.InitialCatalog     = databaseName;
                sqlBuilder.IntegratedSecurity = true;

                // Build the SqlConnection connection string.
                string providerString = sqlBuilder.ToString();

                // Initialize the EntityConnectionStringBuilder.
                EntityConnectionStringBuilder entityBuilder =
                    new EntityConnectionStringBuilder();

                //Set the provider name.
                entityBuilder.Provider = providerName;

                // Set the provider-specific connection string.
                entityBuilder.ProviderConnectionString = providerString;

                // Set the Metadata location.
                entityBuilder.Metadata = @"res://*/SchoolModel.csdl|
                            res://*/SchoolModel.ssdl|
                            res://*/SchoolModel.msl";
                Console.WriteLine(entityBuilder.ToString());

                using (EntityConnection conn =
                           new EntityConnection(entityBuilder.ToString()))
                {
                    conn.Open();

                    using (EntityCommand cmd = conn.CreateCommand())
                    {
                        Console.WriteLine("Creating an EntityCommand with this EntityConnection.");
                        cmd.CommandText = "SELECT VALUE AVG(s.Age) FROM SchoolDbContextEntities.Students as s";
                        // Execute the command.
                        using (EntityDataReader rdr =
                                   cmd.ExecuteReader(CommandBehavior.SequentialAccess))
                        {
                            // Start reading results.
                            while (rdr.Read())
                            {
                                IExtendedDataRecord record = rdr as IExtendedDataRecord;
                                // For PrimitiveType
                                // the record contains exactly one field.
                                int fieldIndex = 0;
                                Console.WriteLine("Value: " + record.GetValue(fieldIndex));
                            }
                        }

                        conn.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
                return((int)ExitCode.UnknownError);
            }

#if NETCOREAPP2_1
            // Add a delay to avoid a race condition on shutdown: https://github.com/dotnet/coreclr/pull/22712
            // This would cause a segmentation fault on .net core 2.x
            System.Threading.Thread.Sleep(5000);
#endif

            return((int)ExitCode.Success);
        }
        /// <summary>
        /// Converts a record to a propagator result
        /// </summary>
        /// <param name="stateEntry">state manager entry containing the record</param>
        /// <param name="isModified">Indicates whether the root element is modified (i.e., whether the type has changed)</param>
        /// <param name="record">Record to convert</param>
        /// <param name="useCurrentValues">Indicates whether we are retrieving current or original values.</param>
        /// <param name="translator">Translator for session context; registers new metadata for the record type if none
        /// exists</param>
        /// <param name="modifiedPropertiesBehavior">Indicates how to determine whether a property is modified.</param>
        /// <returns>Result corresponding to the given record</returns>
        internal static PropagatorResult ExtractResultFromRecord(
            IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record,
            bool useCurrentValues, UpdateTranslator translator, ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            var structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType;
            var metadata = translator.GetExtractorMetadata(stateEntry.EntitySet, structuralType);
            var key = stateEntry.EntityKey;

            var nestedValues = new PropagatorResult[record.FieldCount];
            for (var ordinal = 0; ordinal < nestedValues.Length; ordinal++)
            {
                nestedValues[ordinal] = metadata.RetrieveMember(
                    stateEntry, record, useCurrentValues, key,
                    ordinal, modifiedPropertiesBehavior);
            }

            return PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified);
        }
        /// <summary>
        /// Requires: record must have correct type for this metadata instance.
        /// Populates a new <see cref="PropagatorResult"/> object representing a member of a record matching the 
        /// type of this extractor. Given a record and a member, this method wraps the value of the member
        /// in a PropagatorResult. This operation can be performed efficiently by this class, which knows
        /// important stuff about the type being extracted.
        /// </summary>
        /// <param name="stateEntry">state manager entry containing value (used for error reporting)</param>
        /// <param name="record">Record containing value (used to find the actual value)</param>
        /// <param name="currentValues">Indicates whether we are reading current or original values.</param>
        /// <param name="key">Entity key for the state entry. Must be set for entity records.</param>
        /// <param name="ordinal">Ordinal of Member for which to retrieve a value.</param>
        /// modified (must be ordinally aligned with the type). Null indicates all members are modified.</param>
        /// <param name="modifiedPropertiesBehavior">Indicates how to determine whether a property is modified.</param>
        /// <returns>Propagator result describing this member value.</returns>
        internal PropagatorResult RetrieveMember(
            IEntityStateEntry stateEntry, IExtendedDataRecord record, bool useCurrentValues,
            EntityKey key, int ordinal, ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            var memberInformation = m_memberMap[ordinal];

            // get identifier value
            int identifier;
            if (memberInformation.IsKeyMember)
            {
                // retrieve identifier for this key member
                Debug.Assert(
                    null != (object)key, "entities must have keys, and only entity members are marked IsKeyMember by " +
                                         "the metadata wrapper");
                var keyOrdinal = memberInformation.EntityKeyOrdinal.Value;
                identifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(key, keyOrdinal, ((EntityType)m_type).KeyMembers.Count);
            }
            else if (memberInformation.IsForeignKeyMember)
            {
                identifier = m_translator.KeyManager.GetKeyIdentifierForMember(key, record.GetName(ordinal), useCurrentValues);
            }
            else
            {
                identifier = PropagatorResult.NullIdentifier;
            }

            // determine if the member is modified
            var isModified = modifiedPropertiesBehavior == ModifiedPropertiesBehavior.AllModified ||
                             (modifiedPropertiesBehavior == ModifiedPropertiesBehavior.SomeModified &&
                              stateEntry.ModifiedProperties != null &&
                              stateEntry.ModifiedProperties[memberInformation.Ordinal]);

            // determine member value
            Debug.Assert(record.GetName(ordinal) == memberInformation.Member.Name, "expect record to present properties in metadata order");
            if (memberInformation.CheckIsNotNull
                && record.IsDBNull(ordinal))
            {
                throw EntityUtil.Update(Strings.Update_NullValue(record.GetName(ordinal)), null, stateEntry);
            }
            var value = record.GetValue(ordinal);

            // determine what kind of member this is

            // entityKey (association end)
            var entityKey = value as EntityKey;
            if (null != (object)entityKey)
            {
                return CreateEntityKeyResult(stateEntry, entityKey);
            }

            // record (nested complex type)
            var nestedRecord = value as IExtendedDataRecord;
            if (null != nestedRecord)
            {
                // for structural types, we track whether the entire complex type value is modified or not
                var nestedModifiedPropertiesBehavior = isModified
                                                           ? ModifiedPropertiesBehavior.AllModified
                                                           : ModifiedPropertiesBehavior.NoneModified;
                var translator = m_translator;

                return ExtractResultFromRecord(
                    stateEntry, isModified, nestedRecord, useCurrentValues, translator, nestedModifiedPropertiesBehavior);
            }

            // simple value (column/property value)
            return CreateSimpleResult(stateEntry, record, memberInformation, identifier, isModified, ordinal, value);
        }
        private PropagatorResult CreateSimpleResult(
            IEntityStateEntry stateEntry, IExtendedDataRecord record, MemberInformation memberInformation,
            int identifier, bool isModified, int recordOrdinal, object value)
        {
            var updatableRecord = record as CurrentValueRecord;

            // construct flags for the value, which is needed for complex type and simple members
            var flags = memberInformation.Flags;
            if (!isModified)
            {
                flags |= PropagatorFlags.Preserve;
            }
            if (PropagatorResult.NullIdentifier != identifier)
            {
                // construct a key member
                PropagatorResult result;
                if ((memberInformation.IsServerGenerated || memberInformation.IsForeignKeyMember)
                    && null != updatableRecord)
                {
                    result = PropagatorResult.CreateServerGenKeyValue(flags, value, stateEntry, identifier, recordOrdinal);
                }
                else
                {
                    result = PropagatorResult.CreateKeyValue(flags, value, stateEntry, identifier);
                }

                // we register the entity as the "owner" of an identity so that back-propagation can succeed
                // (keys can only be back-propagated to entities, not association ends). It also allows us
                // to walk to the entity state entry in case of exceptions, since the state entry propagated
                // through the stack may be eliminated in a project above a join.
                m_translator.KeyManager.RegisterIdentifierOwner(result);

                return result;
            }
            else
            {
                if ((memberInformation.IsServerGenerated || memberInformation.IsForeignKeyMember)
                    && null != updatableRecord)
                {
                    // note: we only produce a server gen result when 
                    return PropagatorResult.CreateServerGenSimpleValue(flags, value, updatableRecord, recordOrdinal);
                }
                else
                {
                    return PropagatorResult.CreateSimpleValue(flags, value);
                }
            }
        }