public void depdendencies_are_incremented_when_property_set() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new Mock <IRepositoryFactory>(); var stateTracker = new EntityStateCache(); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory.Object, stateTracker, proxyFactory)) { var factory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var parent = factory.Create(new Parent { Id = "parent" }, session); var child = factory.Create(new Child { Id = "child" }, session); parent.Child = child; var parentState = stateTracker.Get(parent); Assert.Equal(2, parentState.Dependencies.Sequence); var childState = stateTracker.Get(child); Assert.Equal(1, childState.Dependencies.Sequence); } }
/// <exception cref="InvalidOperationException"> /// Attempt to associate non-null <paramref name="tuple"/> with <paramref name="key"/> of unknown type. /// </exception> internal EntityState UpdateStateInCache(Key key, Tuple tuple, bool isStale) { var result = EntityStateCache[key, true]; if (result == null) { if (!key.HasExactType && tuple != null) { throw Exceptions.InternalError( Strings.ExCannotAssociateNonEmptyEntityStateWithKeyOfUnknownType, OrmLog.Instance); } result = AddEntityStateToCache(key, tuple, isStale); SystemEvents.NotifyEntityMaterialized(result); Events.NotifyEntityMaterialized(result); } else { if (!result.Key.HasExactType && key.HasExactType) { EntityStateCache.RemoveKey(result.Key); result = AddEntityStateToCache(key, tuple, result.IsStale); } result.Update(tuple); result.IsStale = isStale; if (IsDebugEventLoggingEnabled) { OrmLog.Debug(Strings.LogSessionXUpdatingCacheY, this, result); } } return(result); }
public void properties_which_are_marked_as_ignored_are_not_proxied() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new Mock <IRepositoryFactory>(); var stateTracker = new EntityStateCache(); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory.Object, stateTracker, proxyFactory)) { var factory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var item = new EntityWithIgnoredProperty { Id = "1", Ignored = new AnotherEntity { Id = "2" }, Proxied = new AnotherEntity { Id = "3" } }; var proxy = factory.Create(item, session); Assert.True(ProxyUtils.IsProxy(proxy)); Assert.True(ProxyUtils.IsProxy(proxy.Proxied)); Assert.False(ProxyUtils.IsProxy(proxy.Ignored)); } }
private async ValueTask RemapEntityKeys(KeyMapping keyMapping, bool isAsync, CancellationToken token = default) { if (keyMapping.Map.Count == 0) { return; } using (Activate()) { if (!LazyKeyGenerationIsEnabled) { await Persist(PersistReason.RemapEntityKeys, isAsync, token).ConfigureAwait(false); Invalidate(); } if (IsDebugEventLoggingEnabled) { OrmLog.Debug(Strings.LogSessionXRemappingEntityKeys, this); } foreach (var entityState in EntityChangeRegistry.GetItems(PersistenceState.New)) { var key = entityState.Key; var remappedKey = keyMapping.TryRemapKey(key); if (remappedKey != key) { entityState.RemapKey(remappedKey); } EntityStateCache.Add(entityState); } ProcessChangesOfEntitySets(entitySetState => entitySetState.RemapKeys(keyMapping)); EntityEvents.RemapKeys(keyMapping); } }
public void objects_with_inheritance_chain_are_proxied_correctly() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new RepositoryFactory(proxyFactory); var parentMapper = new Mock <IMapper <Parent> >(); repositoryFactory.Register <Parent>(x => parentMapper.Object); var childMapper = new Mock <IMapper <Child> >(); repositoryFactory.Register <Child>(x => childMapper.Object); var stateTracker = new EntityStateCache(); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory, stateTracker, proxyFactory)) { var entity = new ParentWithInheritedChild { Id = "1", Type = new SuperTypeA { Id = "1" } }; var proxy = proxyFactory.Create(entity, session); Assert.True(proxy.Type is SuperTypeA); } }
internal void RemapEntityKeys(KeyMapping keyMapping) { if (keyMapping.Map.Count == 0) { return; } using (Activate()) { if (!LazyKeyGenerationIsEnabled) { Persist(PersistReason.RemapEntityKeys); Invalidate(); } OrmLog.Debug(Strings.LogSessionXRemappingEntityKeys, this); foreach (var entityState in EntityChangeRegistry.GetItems(PersistenceState.New)) { var key = entityState.Key; var remappedKey = keyMapping.TryRemapKey(key); if (remappedKey != key) { entityState.RemapKey(remappedKey); } EntityStateCache.Add(entityState); } ProcessChangesOfEntitySets(entitySetState => entitySetState.RemapKeys(keyMapping)); EntityEvents.RemapKeys(keyMapping); } }
internal void RemoveOrCreateRemovedEntity(Type type, Key key, EntityRemoveReason reason) { // Checking for deleted entity with the same key var result = EntityStateCache[key, false]; if (result != null) { if (result.PersistenceState == PersistenceState.Removed) { return; } result.Entity.RemoveLaterInternal(reason); return; } EnforceChangeRegistrySizeLimit(); // Must be done before new entity registration result = new EntityState(this, key, null) { PersistenceState = PersistenceState.Removed }; EntityStateCache.Add(result); if (IsDebugEventLoggingEnabled) { OrmLog.Debug(Strings.LogSessionXCachingY, this, result); } }
public void nullable_types_are_ignored() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new RepositoryFactory(proxyFactory); var parentMapper = new Mock <IMapper <Parent> >(); repositoryFactory.Register <Parent>(x => parentMapper.Object); var childMapper = new Mock <IMapper <Child> >(); repositoryFactory.Register <Child>(x => childMapper.Object); var stateTracker = new EntityStateCache(); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory, stateTracker, proxyFactory)) { var entity = new EntityWithNullableType { Id = "1", Date = DateTime.Now }; var proxy = proxyFactory.Create(entity, session); Assert.NotNull(proxy.Date); } }
public void all_objects_in_the_object_graph_are_proxied() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new Mock <IRepositoryFactory>(); var stateTracker = new EntityStateCache(); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory.Object, stateTracker, proxyFactory)) { var factory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var item = new Person { Id = "1", Contacts = new List <Contact> { new Contact { Id = "1" } } }; var proxy = factory.Create(item, session); Assert.True(ProxyUtils.IsProxy(proxy)); Assert.True(proxy.Contacts is ITrackableCollection <Contact>); Assert.True(ProxyUtils.IsProxy(proxy.Contacts[0])); } }
public void change_tracking_is_applied_when_entity_set_in_constructor() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var mapper = new Mock <IMapper <Parent> >(); var repositoryFactory = new Mock <IRepositoryFactory>(); repositoryFactory.Setup(x => x.Create(It.IsAny <IGraphSession>(), It.IsAny <Type>())).Returns <IGraphSession, Type>((s, t) => new GenericAbstractRepository <Parent>(mapper.Object, s, new DynamicProxyFactory(metadataFactory, new NullLogger()))); var stateTracker = new EntityStateCache(); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory.Object, stateTracker, proxyFactory)) { var proxy = session.Create(new Parent { Id = "1", Child = new Child { Id = "2" } }); var state = stateTracker.Get(proxy.Child); Assert.Equal(EntityStatus.New, state.Status); } }
// IDisposable implementation /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { if (isDisposed) { return; } try { OrmLog.Debug(Strings.LogSessionXDisposing, this); SystemEvents.NotifyDisposing(); Events.NotifyDisposing(); Services.DisposeSafely(); Handler.DisposeSafely(); CommandProcessorContextProvider.DisposeSafely(); Domain.ReleaseSingleConnection(); disposableSet.DisposeSafely(); disposableSet = null; EntityChangeRegistry.Clear(); EntitySetChangeRegistry.Clear(); EntityStateCache.Clear(); ReferenceFieldsChangesRegistry.Clear(); NonPairedReferencesRegistry.Clear(); } finally { isDisposed = true; } }
public void factory_creates_meta_data_correctly_from_a_proxy_object() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new Mock <IRepositoryFactory>(); var stateTracker = new EntityStateCache(); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory.Object, stateTracker, proxyFactory)) { var factory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var item = new Parent { Id = "1", Child = new Child { Id = "2" }, Children = new List <Child> { new Child { Id = "3" } } }; var proxy = factory.Create(item, session); var parentMetadata = metadataFactory.Create(proxy); Assert.Equal("Parent", parentMetadata.Name); var childMetadta = metadataFactory.Create(proxy.Child); Assert.Equal("Child", childMetadta.Name); } }
public void circular_dependencies_are_proxied_correctly() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new RepositoryFactory(proxyFactory); var parentMapper = new Mock <IMapper <Parent> >(); repositoryFactory.Register <Parent>(x => parentMapper.Object); var childMapper = new Mock <IMapper <Child> >(); repositoryFactory.Register <Child>(x => childMapper.Object); var stateTracker = new EntityStateCache(); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory, stateTracker, proxyFactory)) { var a = new EntityA { Id = "a" }; var b = new EntityB { Id = "b" }; a.EntityB = b; b.EntityA = a; var proxy = proxyFactory.Create(a, session); Assert.NotNull(proxy); Assert.NotNull(proxy.EntityB); Assert.NotNull(proxy.EntityB.EntityA); Assert.Same(proxy, proxy.EntityB.EntityA); } }
public void dependencies_are_incremented_as_relationships_are_created() { var stateTracker = new EntityStateCache(); var stateFactory = new Mock <IEntityStateCacheFactory>(); stateFactory.Setup(x => x.Create()).Returns(stateTracker); var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new RepositoryFactory(proxyFactory); repositoryFactory.Register <Organisation>(session => new Mapper <Organisation>(session, metadataFactory)); repositoryFactory.Register <AccessGroup>(session => new Mapper <AccessGroup>(session, metadataFactory)); repositoryFactory.Register <Site>(session => new Mapper <Site>(session, metadataFactory)); repositoryFactory.Register <Person>(session => new Mapper <Person>(session, metadataFactory)); var sessionFactory = new GraphSessionFactory(queryExecutorFactory.Object, repositoryFactory, stateFactory.Object, proxyFactory); using (var session = sessionFactory.OpenSession()) { var organisation = session.Create(new Organisation { Id = "organisation" }); var site = session.Create(new Site { Id = "site" }); var accessGroup = session.Create(new AccessGroup { Id = "accessGroup" }); var person = session.Create(new Person { Id = "person" }); organisation.Add(site); organisation.Add(accessGroup); site.Add(accessGroup); person.Add(organisation); person.Add(site); var organisationMetadata = stateTracker.Get(organisation); var siteMetadata = stateTracker.Get(site); var accessGroupMetadata = stateTracker.Get(accessGroup); var personMetadata = stateTracker.Get(person); Assert.Equal(1, accessGroupMetadata.Dependencies.Sequence); Assert.Equal(2, siteMetadata.Dependencies.Sequence); Assert.Equal(3, organisationMetadata.Dependencies.Sequence); Assert.Equal(4, personMetadata.Dependencies.Sequence); } }
private EntityState AddEntityStateToCache(Key key, Tuple tuple, bool isStale) { var result = new EntityState(this, key, tuple, isStale) { PersistenceState = PersistenceState.Synchronized }; EntityStateCache.Add(result); OrmLog.Debug(Strings.LogSessionXCachingY, this, result); return(result); }
public void interceptors_are_not_created_for_re_entrant_proxies() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new RepositoryFactory(proxyFactory); var parentMapper = new Mock <IMapper <Parent> >(); repositoryFactory.Register <Parent>(x => parentMapper.Object); var childMapper = new Mock <IMapper <Child> >(); repositoryFactory.Register <Child>(x => childMapper.Object); var stateTracker = new EntityStateCache(); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory, stateTracker, proxyFactory)) { var proxy = session.Create(new Parent { Id = "1" }); proxy.Child = session.Create(new Child { Id = "1" }); var metadata = metadataFactory.Create(proxy); var deleted = ProxyUtils.Flush(proxy, metadata["Child"].Relationship); Assert.Equal(0, deleted.SelectMany(x => x.Flush().Cast <object>()).Count()); var reentrant = session.Create(proxy); Assert.Equal(proxy, reentrant); metadata = metadataFactory.Create(reentrant); deleted = ProxyUtils.Flush(reentrant, metadata["Child"].Relationship); Assert.Equal(0, deleted.SelectMany(x => x.Flush().Cast <object>()).Count()); proxy.Child = session.Create(new Child { Id = "2" }); metadata = metadataFactory.Create(reentrant); deleted = ProxyUtils.Flush(reentrant, metadata["Child"].Relationship); Assert.Equal(1, deleted.SelectMany(x => x.Flush().Cast <object>()).Count()); } }
public void properties_set_during_construction_are_restored_after_proxy_created() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new Mock <IRepositoryFactory>(); var stateTracker = new EntityStateCache(); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory.Object, stateTracker, proxyFactory)) { var factory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var item = new EntityWithPropertiesSetInConstructor("1", "Test"); var proxy = factory.Create(item, session); Assert.Equal("1", proxy.Id); Assert.Equal("Test", proxy.Name); } }
private async ValueTask DisposeImpl(bool isAsync) { if (isDisposed) { return; } sessionLifetimeToken.Expire(); try { if (IsDebugEventLoggingEnabled) { OrmLog.Debug(Strings.LogSessionXDisposing, this); } SystemEvents.NotifyDisposing(); Events.NotifyDisposing(); Services.DisposeSafely(); if (isAsync) { await Handler.DisposeSafelyAsync().ConfigureAwait(false); } else { Handler.DisposeSafely(); } CommandProcessorContextProvider.DisposeSafely(); Domain.ReleaseSingleConnection(); disposableSet.DisposeSafely(); disposableSet = null; EntityChangeRegistry.Clear(); EntitySetChangeRegistry.Clear(); EntityStateCache.Clear(); ReferenceFieldsChangesRegistry.Clear(); NonPairedReferencesRegistry.Clear(); Extensions.Clear(); } finally { isDisposed = true; } }
public void an_exception_is_thrown_if_id_null() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new Mock <IRepositoryFactory>(); var stateTracker = new EntityStateCache(); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory.Object, stateTracker, proxyFactory)) { Assert.Throws <PropertyNotSetException>(() => { var factory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var notSet = new AnotherEntity(); factory.Create(notSet, session); }); } }
internal EntityState CreateEntityState(Key key, bool failIfStateIsAlreadyBound) { // Checking for deleted entity with the same key var result = EntityStateCache[key, false]; EnforceChangeRegistrySizeLimit(); // Must be done before new entity registration // If type is unknown, we consider tuple is null, // so its Entity is considered as non-existing Tuple tuple = null; if (key.HasExactType) { // A tuple with all the fields set to default values rather then N/A var typeInfo = key.TypeInfo; tuple = typeInfo.CreateEntityTuple(key.Value, StorageNode.TypeIdRegistry[typeInfo]); } if (result == null) { result = new EntityState(this, key, tuple) { PersistenceState = PersistenceState.New }; EntityStateCache.Add(result); } else { if (result.Entity != null && !result.Entity.IsRemoved && failIfStateIsAlreadyBound) { throw new UniqueConstraintViolationException(string.Format(Strings.ExEntityWithKeyXAlreadyExists, key)); } result.Key = key; result.Tuple = tuple; result.PersistenceState = PersistenceState.New; } if (IsDebugEventLoggingEnabled) { OrmLog.Debug(Strings.LogSessionXCachingY, this, result); } return(result); }
public void a_proxy_is_generated_for_trackable_relationships() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new Mock <IRepositoryFactory>(); var stateTracker = new EntityStateCache(); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory.Object, stateTracker, proxyFactory)) { var person = new Person { Id = "1", Name = "Test", Address = new Address { Id = "1", Name = "first address" } }; var proxy = proxyFactory.Create(person, session); proxy.Address = null; proxy.Address = proxyFactory.Create(new Address { Id = "2" }, session); var metadata = metadataFactory.Create(proxy); var trackableRelationships = ProxyUtils.Flush(proxy, metadata["Address"].Relationship).ToList(); Assert.Equal(1, trackableRelationships.Count); foreach (var trackableRelationship in trackableRelationships) { var enumerable = trackableRelationship.Flush(); var results = enumerable.Cast <object>().ToList(); Assert.Equal(1, results.Count); Assert.Equal("1", ((Address)results[0]).Id); Assert.Equal("2", proxy.Address.Id); } } }
public void reverse_property_is_set_correctly_on_one_to_one_relationships() { var metadataFactory = new AttributeMetadataFactory(new NullLogger()); var queryExecutorFactory = new Mock <IQueryExecutorFactory>(); var repositoryFactory = new Mock <IRepositoryFactory>(); var stateTracker = new EntityStateCache(); var proxyFactory = new DynamicProxyFactory(metadataFactory, new NullLogger()); using (var session = new GraphSession(new UnitOfWork(stateTracker), new List <IListener>(), queryExecutorFactory.Object, repositoryFactory.Object, stateTracker, proxyFactory)) { var factory = new DynamicProxyFactory(metadataFactory, new NullLogger()); var alpha = factory.Create(new ClassAlpha { Id = "1" }, session); var beta = factory.Create(new ClassBeta { Id = "2" }, session); alpha.Beta = beta; var metadata = metadataFactory.Create(beta); Assert.True(metadata["Alpha"].Relationship.IsReverse); } }
internal void RemoveStateFromCache(Key key, bool removeFromInnerCache = false) { EntityStateCache.RemoveKey(key, removeFromInnerCache); }
public CacheManager(EntityAreaCache entityAreaCache, EntityStateCache entityStateCache) { _entityAreaCache = entityAreaCache; _entityStateCache = entityStateCache; }
internal bool LookupStateInCache(Key key, out EntityState entityState) { return(EntityStateCache.TryGetItem(key, true, out entityState)); }