コード例 #1
0
        public void MapAndMerge(AbstractEntity entity, MappingEngineCollection mappers)
        {
            using (DisposableTimer.TraceDuration <NhSessionHelper>("Start MapAndMerge for entity " + entity.Id, "End MapAndMerge"))
                using (NhProfilerLogging.Start(NhSession, "MapAndMerge",
                                               new OdbcParameter("entity", entity)))
                {
                    var rdbmsEntity = mappers.MapToIntent <IReferenceByGuid>(entity);

                    // Track ID generation on the Rdbms object so that it can be pinged to the AbstractEntity upon Save/Update commit
                    rdbmsEntity = NhSession.Merge(rdbmsEntity) as IReferenceByGuid;

                    //InnerDataContext.NhibernateSession.SaveOrUpdate(rdbmsEntity);
                    mappers.Map(rdbmsEntity, entity, rdbmsEntity.GetType(), entity.GetType());
                }
        }
コード例 #2
0
        public void MapAndMerge <T>(Revision <T> entity, MappingEngineCollection mappers) where T : class, IVersionableEntity
        {
            HiveId hiveId   = entity.MetaData != null ? entity.MetaData.Id : HiveId.Empty;
            HiveId entityId = entity.Item != null ? entity.Item.Id : HiveId.Empty;

            using (DisposableTimer.TraceDuration <NhSessionHelper>("Start MapAndMerge for revision " + hiveId + " entity " + entityId, "End MapAndMerge"))
                using (NhProfilerLogging.Start(NhSession, "MapAndMerge<T> (Revision<T>)",
                                               new OdbcParameter("entity", entity)))
                {
                    var rdbmsEntity = mappers.MapToIntent <IReferenceByGuid>(entity);

                    // Track ID generation on the Rdbms object so that it can be pinged to the AbstractEntity upon Save/Update commit
                    rdbmsEntity = NhSession.Merge(rdbmsEntity) as IReferenceByGuid;

                    // 16th Jan 12 (APN) NH is not flushing if the above merged entity is queried before the transaction is committed, despite
                    // the flushmode being Auto. So, explicit call to Flush here pending a bugfix/ better solution
                    NhSession.Flush();

                    //InnerDataContext.NhibernateSession.SaveOrUpdate(rdbmsEntity);
                    mappers.Map(rdbmsEntity, entity, rdbmsEntity.GetType(), entity.GetType());
                }
        }
コード例 #3
0
        public void AddRelation(IReadonlyRelation <IRelatableEntity, IRelatableEntity> item, AbstractScopedCache repositoryScopedCache)
        {
            var sessionIdAsString = GetSessionId().ToString("n");

            using (DisposableTimer.TraceDuration <NhSessionHelper>("In AddRelation for session " + sessionIdAsString, "End AddRelation for session " + sessionIdAsString))
            {
                // Get the source and destination items from the Nh session
                var sourceNode = NhSession.Get <Node>((Guid)item.SourceId.Value);
                var destNode   = NhSession.Get <Node>((Guid)item.DestinationId.Value);

                // Check the Nh session is already aware of the items
                if (sourceNode == null || destNode == null)
                {
                    string extraMessage = string.Empty;
                    if (sourceNode == null)
                    {
                        extraMessage = "Source {0} cannot be found.\n".InvariantFormat(item.SourceId.Value);
                    }
                    if (destNode == null)
                    {
                        extraMessage += "Destination {0} cannot be found.".InvariantFormat(item.DestinationId.Value);
                    }
                    throw new InvalidOperationException(
                              "Before adding a relation between source {0} and destination {1}, you must call AddOrUpdate with those items or they must already exist in the datastore.\n{2}"
                              .InvariantFormat(item.SourceId, item.DestinationId, extraMessage));
                }

                // Try to load an existing relation of the same type between the two
                var relationType = GetOrCreateNodeRelationType(item.Type.RelationName, repositoryScopedCache);

                // Grab the existing relation (if exists) using the compound key of start node / end node / relation type
                var cacheKey = GenerateCacheKeyForRelation(item, relationType);

                NodeRelation relationToReturn = repositoryScopedCache.GetOrCreateTyped(
                    cacheKey,
                    () =>
                {
                    return(NhSession
                           .QueryOver <NodeRelation>()
                           .Where(x => x.StartNode == sourceNode && x.EndNode == destNode && x.NodeRelationType == relationType)
                           .Cacheable()
                           .SingleOrDefault());
                });

                // Avoid a duplicate by checking if one already exists
                if (relationToReturn != null)
                {
                    // Make sure existing relation has ordinal
                    relationToReturn.Ordinal = item.Ordinal;
                }
                else
                {
                    // Create a new relation
                    relationToReturn = new NodeRelation {
                        StartNode = sourceNode, EndNode = destNode, NodeRelationType = relationType, Ordinal = item.Ordinal
                    };
                    relationToReturn = NhSession.Merge(relationToReturn) as NodeRelation;
                }

                // Ensure metadata correct on existing or new entity
                CreateAndAddRelationTags(item, relationToReturn);
            }
        }