public override object Next(StateEntry entry, IProperty property) { Check.NotNull(property, "property"); Contract.Assert(property.IsForeignKey()); var entityType = property.EntityType; var stateManager = entry.Configuration.StateManager; foreach (var foreignKey in entityType.ForeignKeys) { for (var propertyIndex = 0; propertyIndex < foreignKey.Properties.Count; propertyIndex++) { if (property == foreignKey.Properties[propertyIndex]) { foreach (var navigation in entityType.Navigations .Concat(foreignKey.ReferencedEntityType.Navigations) .Where(n => n.ForeignKey == foreignKey) .Distinct()) { var principal = TryFindPrincipal(stateManager, navigation, entry.Entity); if (principal != null) { var principalEntry = stateManager.GetOrCreateEntry(principal); return principalEntry[foreignKey.ReferencedProperties[propertyIndex]]; } } } } } return null; }
public override object Next(StateEntry entry, IProperty property) { Check.NotNull(entry, "entry"); Check.NotNull(property, "property"); return Convert.ChangeType(Interlocked.Increment(ref _current), property.PropertyType); }
public virtual async Task<object> NextAsync(StateEntry stateEntry, IProperty property, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(stateEntry, "stateEntry"); Check.NotNull(property, "property"); var newValue = GetNextValue(); // If the chosen value is outside of the current block then we need a new block. // It is possible that other threads will use all of the new block before this thread // gets a chance to use the new new value, so use a while here to do it all again. while (newValue.Current >= newValue.Max) { // Once inside the lock check to see if another thread already got a new block, in which // case just get a value out of the new block instead of requesting one. using (await _lock.LockAsync(cancellationToken)) { if (newValue.Max == _currentValue.Max) { var commandInfo = PrepareCommand(stateEntry.Configuration); var newCurrent = (long)await _executor.ExecuteScalarAsync(commandInfo.Item1.DbConnection, commandInfo.Item1.DbTransaction, commandInfo.Item2, cancellationToken).ConfigureAwait(false); newValue = new SequenceValue(newCurrent, newCurrent + _blockSize); _currentValue = newValue; } else { newValue = GetNextValue(); } } } return Convert.ChangeType(newValue.Current, property.PropertyType); }
public override object Next(StateEntry entry, IProperty property) { Check.NotNull(entry, "entry"); Check.NotNull(property, "property"); return Guid.NewGuid(); }
private void ForeignKeyPropertyChangedAction(StateEntry entry, IProperty property, object oldValue, object newValue) { var stateManager = _configuration.StateManager; foreach (var foreignKey in entry.EntityType.ForeignKeys.Where(p => p.Properties.Contains(property)).Distinct()) { var navigations = stateManager.Model.GetNavigations(foreignKey).ToArray(); var oldPrincipalEntry = stateManager.GetPrincipal(entry.RelationshipsSnapshot, foreignKey); if (oldPrincipalEntry != null) { Unfixup(navigations, oldPrincipalEntry, entry); } var principalEntry = stateManager.GetPrincipal(entry, foreignKey); if (principalEntry != null) { if (foreignKey.IsUnique) { var oldDependents = stateManager.GetDependents(principalEntry, foreignKey).Where(e => e != entry).ToArray(); // TODO: Decide how to handle case where multiple values found (negative case) if (oldDependents.Length > 0) { StealReference(foreignKey, oldDependents[0]); } } DoFixup(navigations, principalEntry, new[] { entry }); } } }
public virtual void ForeignKeyPropertyChanged(StateEntry entry, IProperty property, object oldValue, object newValue) { Check.NotNull(entry, "entry"); Check.NotNull(property, "property"); PerformFixup(() => ForeignKeyPropertyChangedAction(entry, property, oldValue, newValue)); }
private static IEnumerable<IPropertyBase> GetProperties(StateEntry stateEntry) { var entityType = stateEntry.EntityType; return entityType.GetKey().Properties.Concat( entityType.ForeignKeys.SelectMany(fk => fk.Properties)).Distinct() .Concat<IPropertyBase>(entityType.Navigations); }
public PropertyEntry([NotNull] StateEntry stateEntry, [NotNull] string name) { Check.NotNull(stateEntry, "stateEntry"); Check.NotEmpty(name, "name"); _stateEntry = stateEntry; _property = stateEntry.EntityType.GetProperty(name); }
public virtual Task<object> NextAsync( StateEntry stateEntry, IProperty property, CancellationToken cancellationToken = default(CancellationToken)) { Check.NotNull(stateEntry, "stateEntry"); Check.NotNull(property, "property"); return Task.FromResult(Next(stateEntry, property)); }
private Func<StateEntry, ITableEntity> GetOrMakeAdapter(StateEntry entry) { return _instanceCreatorCache.GetOrAdd(entry, e => { var paramExpression = new[] { Expression.Parameter(typeof(StateEntry), "entry") }; var ctorExpression = Expression.New( typeof(StateEntryTableEntityAdapter<>) .MakeGenericType(e.Entity.GetType()) .GetConstructor(new[] { typeof(StateEntry) }), paramExpression ); var lambda = Expression.Lambda<Func<StateEntry, ITableEntity>>(ctorExpression, paramExpression); return lambda.Compile(); }); }
private bool DetectForeignKeyChange(StateEntry entry, IProperty property) { if (property.IsForeignKey()) { var snapshotValue = entry.RelationshipsSnapshot[property]; var currentValue = entry[property]; // Note that mutation of a byte[] key is not supported or detected, but two different instances // of byte[] with the same content must be detected as equal. if (!StructuralComparisons.StructuralEqualityComparer.Equals(currentValue, snapshotValue)) { entry.StateManager.Notify.ForeignKeyPropertyChanged(entry, property, snapshotValue, currentValue); return(true); } } return(false); }
private void DetectKeyChange(StateEntry entry, IProperty property, Sidecar snapshot) { if (!snapshot.HasValue(property)) { return; } // TODO: Perf: make it fast to check if a property is part of any key var isPrimaryKey = property.IsPrimaryKey(); var isPrincipalKey = _model.Service.GetReferencingForeignKeys(property).Any(); var isForeignKey = property.IsForeignKey(); if (isPrimaryKey || isPrincipalKey || isForeignKey) { var snapshotValue = snapshot[property]; var currentValue = entry[property]; // Note that mutation of a byte[] key is not supported or detected, but two different instances // of byte[] with the same content must be detected as equal. if (!StructuralComparisons.StructuralEqualityComparer.Equals(currentValue, snapshotValue)) { if (isForeignKey) { entry.StateManager.Notify.ForeignKeyPropertyChanged(entry, property, snapshotValue, currentValue); } if (isPrimaryKey) { entry.StateManager.UpdateIdentityMap(entry, snapshot.GetPrimaryKeyValue()); } if (isPrincipalKey) { entry.StateManager.Notify.PrincipalKeyPropertyChanged(entry, property, snapshotValue, currentValue); } snapshot.TakeSnapshot(property); } } }
public virtual void ForeignKeyPropertyChanged(StateEntry entry, IProperty property, object oldValue, object newValue) { Check.NotNull(entry, "entry"); Check.NotNull(property, "property"); foreach (var foreignKey in entry.EntityType.ForeignKeys.Where(p => p.Properties.Contains(property)).Distinct()) { var oldPrincipalEntry = _stateManager.GetPrincipal(entry, foreignKey, useForeignKeySnapshot: true); if (oldPrincipalEntry != null) { UndoFixup(foreignKey, oldPrincipalEntry, entry); } var principalEntry = _stateManager.GetPrincipal(entry, foreignKey, useForeignKeySnapshot: false); if (principalEntry != null) { DoFixup(foreignKey, principalEntry, new[] { entry }); } } }
private void PrincipalKeyPropertyChangedAction(StateEntry entry, IProperty property, object oldValue, object newValue) { foreach (var foreignKey in _model.Service.EntityTypes.SelectMany( e => e.ForeignKeys.Where(f => f.ReferencedProperties.Contains(property)))) { var newKeyValues = foreignKey.ReferencedProperties.Select(p => entry[p]).ToList(); var oldKey = entry.RelationshipsSnapshot.GetPrincipalKeyValue(foreignKey); foreach (var dependent in entry.StateManager.StateEntries.Where( e => e.EntityType == foreignKey.EntityType && oldKey.Equals(e.GetDependentKeyValue(foreignKey))).ToList()) { if (dependent.TryGetSidecar(Sidecar.WellKnownNames.StoreGeneratedValues) == null) { dependent.AddSidecar(_storeGeneratedValuesFactory.Create(dependent)); } SetForeignKeyValue(dependent, foreignKey.Properties, newKeyValues); } } }
public virtual StateEntry GetPrincipal([NotNull] StateEntry dependentEntry, [NotNull] IForeignKey foreignKey) { Check.NotNull(dependentEntry, "dependentEntry"); Check.NotNull(foreignKey, "foreignKey"); var dependentKeyValue = dependentEntry.GetDependentKeyValue(foreignKey); // TODO: Add additional indexes so that this isn't a linear lookup var principals = StateEntries.Where( e => e.EntityType == foreignKey.ReferencedEntityType && dependentKeyValue.Equals(e.GetPrincipalKeyValue(foreignKey))).ToArray(); if (principals.Length > 1) { // TODO: Better exception message throw new InvalidOperationException("Multiple matching principals."); } return(principals.FirstOrDefault()); }
public virtual void StartTracking([NotNull] StateEntry entry) { Check.NotNull(entry, "entry"); var entityType = entry.EntityType; if (entry.Configuration.Services.StateManager != this) { throw new InvalidOperationException(Strings.FormatWrongStateManager(entityType.Name)); } StateEntry existingEntry; if (entry.Entity != null) { if (!_entityReferenceMap.TryGetValue(entry.Entity, out existingEntry)) { _entityReferenceMap[entry.Entity] = entry; } else if (existingEntry != entry) { throw new InvalidOperationException(Strings.FormatMultipleStateEntries(entityType.Name)); } } var keyValue = CreateKey(entityType, entityType.GetKey().Properties, entry); if (_identityMap.TryGetValue(keyValue, out existingEntry)) { if (existingEntry != entry) { // TODO: Consider a hook for identity resolution // TODO: Consider specialized exception types throw new InvalidOperationException(Strings.FormatIdentityConflict(entityType.Name)); } } else { _identityMap[keyValue] = entry; } }
public virtual void SidecarPropertyChanged(StateEntry entry, IPropertyBase propertyBase) { Check.NotNull(entry, "entry"); Check.NotNull(propertyBase, "propertyBase"); var property = propertyBase as IProperty; if (property == null) { return; } var snapshot = entry.TryGetSidecar(Sidecar.WellKnownNames.RelationshipsSnapshot); if (snapshot == null) { return; } DetectKeyChange(entry, property, snapshot); }
public virtual void StopTracking([NotNull] StateEntry entry) { Check.NotNull(entry, "entry"); if (entry.Entity != null) { _entityReferenceMap.Remove(entry.Entity); } var entityType = entry.EntityType; var keyValue = CreateKey(entityType, entityType.GetKey().Properties, entry); StateEntry existingEntry; if (_identityMap.TryGetValue(keyValue, out existingEntry) && existingEntry == entry) { _identityMap.Remove(keyValue); } }
private void ConditionallyClearInverse(StateEntry entry, INavigation navigation, object entity) { var inverse = navigation.TryGetInverse(); if (inverse != null) { if (inverse.IsCollection()) { _collectionAccessorSource.GetAccessor(inverse).Remove(entity, entry.Entity); } else { if (ReferenceEquals(_getterSource.GetAccessor(inverse).GetClrValue(entity), entry.Entity)) { _setterSource.GetAccessor(inverse).SetClrValue(entity, null); } } entry.StateManager.GetOrCreateEntry(entity).RelationshipsSnapshot.TakeSnapshot(inverse); } }
private void StealReference(IForeignKey foreignKey, StateEntry dependentEntry) { foreach (var navigation in dependentEntry.EntityType.Navigations.Where(n => n.ForeignKey == foreignKey)) { if (navigation.PointsToPrincipal) { _setterSource.GetAccessor(navigation).SetClrValue(dependentEntry.Entity, null); dependentEntry.RelationshipsSnapshot.TakeSnapshot(navigation); } } var nullableProperties = foreignKey.Properties.Where(p => p.IsNullable).ToList(); if (nullableProperties.Count > 0) { foreach (var property in nullableProperties) { dependentEntry[property] = null; } } }
public virtual StateEntry SnapshotAndSubscribe([NotNull] StateEntry entry) { var entityType = entry.EntityType; if (!entityType.UseLazyOriginalValues) { entry.OriginalValues.TakeSnapshot(); entry.RelationshipsSnapshot.TakeSnapshot(); } var changing = entry.Entity as INotifyPropertyChanging; if (changing != null) { changing.PropertyChanging += (s, e) => { var property = TryGetPropertyBase(entityType, e.PropertyName); if (property != null) { _notifier.PropertyChanging(entry, property); } }; } var changed = entry.Entity as INotifyPropertyChanged; if (changed != null) { changed.PropertyChanged += (s, e) => { var property = TryGetPropertyBase(entityType, e.PropertyName); if (property != null) { _notifier.PropertyChanged(entry, property); } }; } return(entry); }
private void NavigationCollectionChangedAction( StateEntry entry, INavigation navigation, IEnumerable <object> added, IEnumerable <object> removed) { Debug.Assert(navigation.IsCollection()); var dependentProperties = navigation.ForeignKey.Properties; var principalValues = navigation.ForeignKey.ReferencedProperties.Select(p => entry[p]).ToList(); // TODO: What if the entity is not yet being tracked? // Issue #323 foreach (var entity in removed) { ConditionallySetNullForeignKey(entry.StateManager.GetOrCreateEntry(entity), dependentProperties, principalValues); ConditionallyClearInverse(entry, navigation, entity); } foreach (var entity in added) { SetForeignKeyValue(entry.StateManager.GetOrCreateEntry(entity), dependentProperties, principalValues); SetInverse(entry, navigation, entity); } }
public virtual void PrincipalKeyPropertyChanged(StateEntry entry, IProperty property, object oldValue, object newValue) { Check.NotNull(entry, "entry"); Check.NotNull(property, "property"); // We don't prevent recursive entry here because changed of principal key can have cascading effects // when principal key is also foreign key. foreach (var foreignKey in _model.Service.EntityTypes.SelectMany( e => e.ForeignKeys.Where(f => f.ReferencedProperties.Contains(property)))) { var newKeyValues = foreignKey.ReferencedProperties.Select(p => entry[p]).ToList(); var oldKey = entry.RelationshipsSnapshot.GetPrincipalKeyValue(foreignKey); foreach (var dependent in entry.StateManager.StateEntries.Where( e => e.EntityType == foreignKey.EntityType && oldKey.Equals(e.GetDependentKeyValue(foreignKey))).ToList()) { SetForeignKeyValue(foreignKey, dependent, newKeyValues); } } }
public virtual StateEntry SnapshotAndSubscribe([NotNull] StateEntry entry) { if (!entry.EntityType.UseLazyOriginalValues) { entry.OriginalValues.TakeSnapshot(); entry.ForeignKeysSnapshot.TakeSnapshot(); } var changing = entry.Entity as INotifyPropertyChanging; if (changing != null) { changing.PropertyChanging += (s, e) => { var property = entry.EntityType.TryGetProperty(e.PropertyName); if (property != null) { entry.PropertyChanging(property); } }; } var changed = entry.Entity as INotifyPropertyChanged; if (changed != null) { changed.PropertyChanged += (s, e) => { var property = entry.EntityType.TryGetProperty(e.PropertyName); if (property != null) { entry.PropertyChanged(property); } }; } return(entry); }
private void DoFixup(IEnumerable <INavigation> navigations, StateEntry principalEntry, StateEntry[] dependentEntries) { foreach (var navigation in navigations) { if (navigation.PointsToPrincipal) { var setter = _setterSource.GetAccessor(navigation); foreach (var dependent in dependentEntries) { setter.SetClrValue(dependent.Entity, principalEntry.Entity); dependent.RelationshipsSnapshot.TakeSnapshot(navigation); } } else { if (navigation.IsCollection()) { var collectionAccessor = _collectionAccessorSource.GetAccessor(navigation); foreach (var dependent in dependentEntries) { if (!collectionAccessor.Contains(principalEntry.Entity, dependent.Entity)) { collectionAccessor.Add(principalEntry.Entity, dependent.Entity); } } } else { // TODO: Decide how to handle case where multiple values match non-collection nav prop // Issue #739 _setterSource.GetAccessor(navigation).SetClrValue(principalEntry.Entity, dependentEntries.Single().Entity); } principalEntry.RelationshipsSnapshot.TakeSnapshot(navigation); } } }
private void SetInverse(StateEntry entry, INavigation navigation, object entity) { var inverse = navigation.TryGetInverse(); if (inverse != null) { if (inverse.IsCollection()) { var collectionAccessor = _collectionAccessorSource.GetAccessor(inverse); if (!collectionAccessor.Contains(entity, entry.Entity)) { collectionAccessor.Add(entity, entry.Entity); } } else { _setterSource.GetAccessor(inverse).SetClrValue(entity, entry.Entity); } entry.StateManager.GetOrCreateEntry(entity).RelationshipsSnapshot.TakeSnapshot(inverse); } }
private void Unfixup(INavigation navigation, StateEntry oldPrincipalEntry, StateEntry dependentEntry) { if (navigation.PointsToPrincipal) { _setterSource.GetAccessor(navigation).SetClrValue(dependentEntry.Entity, null); dependentEntry.RelationshipsSnapshot.TakeSnapshot(navigation); } else { if (navigation.IsCollection()) { var collectionAccessor = _collectionAccessorSource.GetAccessor(navigation); if (collectionAccessor.Contains(oldPrincipalEntry.Entity, dependentEntry.Entity)) { collectionAccessor.Remove(oldPrincipalEntry.Entity, dependentEntry.Entity); } } else { _setterSource.GetAccessor(navigation).SetClrValue(oldPrincipalEntry.Entity, null); } } }
public ColumnModification( [NotNull] StateEntry stateEntry, [NotNull] IProperty property, [CanBeNull] string parameterName, [CanBeNull] string originalParameterName, bool isRead, bool isWrite, bool isKey, bool isCondition) { Check.NotNull(stateEntry, "stateEntry"); Check.NotNull(property, "property"); _stateEntry = stateEntry; _property = property; _columnName = property.ColumnName(); _parameterName = parameterName; _originalParameterName = originalParameterName; _isRead = isRead; _isWrite = isWrite; _isKey = isKey; _isCondition = isCondition; }
public virtual void PropertyChanging(StateEntry entry, IPropertyBase propertyBase) { Check.NotNull(entry, "entry"); Check.NotNull(propertyBase, "propertyBase"); if (!entry.EntityType.UseEagerSnapshots) { var property = propertyBase as IProperty; if (property != null && property.OriginalValueIndex >= 0) { entry.OriginalValues.EnsureSnapshot(property); } var navigation = propertyBase as INavigation; if ((navigation != null && !navigation.IsCollection()) || (property != null && (property.IsKey() || property.IsForeignKey()))) { // TODO: Consider making snapshot temporary here since it is no longer required after PropertyChanged is called // See issue #730 entry.RelationshipsSnapshot.TakeSnapshot(propertyBase); } } }
public override object Next(StateEntry entry, IProperty property) { Check.NotNull(entry, "entry"); Check.NotNull(property, "property"); var guidBytes = Guid.NewGuid().ToByteArray(); var counterBytes = BitConverter.GetBytes(Interlocked.Increment(ref _counter)); if (!BitConverter.IsLittleEndian) { Array.Reverse(counterBytes); } guidBytes[08] = counterBytes[1]; guidBytes[09] = counterBytes[0]; guidBytes[10] = counterBytes[7]; guidBytes[11] = counterBytes[6]; guidBytes[12] = counterBytes[5]; guidBytes[13] = counterBytes[4]; guidBytes[14] = counterBytes[3]; guidBytes[15] = counterBytes[2]; return new Guid(guidBytes); }
public void PrincipalKeyPropertyChanged(StateEntry entry, IProperty property, object oldValue, object newValue) { }
public void NavigationReferenceChanged(StateEntry entry, INavigation navigation, object oldValue, object newValue) { }
public void StateChanged(StateEntry entry, EntityState oldState) { }
public virtual Sidecar CreateRelationshipSnapshot([NotNull] StateEntry stateEntry) { Check.NotNull(stateEntry, "stateEntry"); return(_relationshipsSnapshotFactory.Create(stateEntry)); }
private static void ConditionallySetNullForeignKey( StateEntry dependentEntry, IReadOnlyList<IProperty> dependentProperties, StateEntry principalEntry, IReadOnlyList<IProperty> principalProperties) { ConditionallySetNullForeignKey(dependentEntry, dependentProperties, principalProperties.Select(p => principalEntry[p]).ToArray()); }
protected override Sidecar CreateSidecar(StateEntry entry = null) { return new StoreGeneratedValuesFactory().Create(entry ?? CreateStateEntry()); }
private static void ConditionallySetNullForeignKey( StateEntry dependentEntry, IReadOnlyList<IProperty> dependentProperties, IReadOnlyList<object> principalValues) { // Don't null out the FK if it has already be set to point to a different principal if (dependentProperties.Select(p => dependentEntry[p]).StructuralSequenceEqual(principalValues)) { SetNullForeignKey(dependentEntry, dependentProperties); } }
public virtual void NavigationReferenceChanged(StateEntry entry, INavigation navigation, object oldValue, object newValue) { Check.NotNull(entry, "entry"); Check.NotNull(navigation, "navigation"); PerformFixup(() => NavigationReferenceChangedAction(entry, navigation, oldValue, newValue)); }
protected ArraySidecar([NotNull] StateEntry stateEntry, int count) : base(stateEntry) { _values = new object[count]; }
public EntityEntry([NotNull] StateEntry stateEntry) { Check.NotNull(stateEntry, "stateEntry"); _stateEntry = stateEntry; }
private void NavigationReferenceChangedAction(StateEntry entry, INavigation navigation, object oldValue, object newValue) { var foreignKey = navigation.ForeignKey; var dependentProperties = foreignKey.Properties; var principalProperties = foreignKey.ReferencedProperties; var stateManager = _configuration.StateManager; // TODO: What if the other entry is not yet being tracked? if (navigation.PointsToPrincipal) { if (newValue != null) { SetForeignKeyValue(entry, dependentProperties, stateManager.GetOrCreateEntry(newValue), principalProperties); } else { SetNullForeignKey(entry, dependentProperties); } } else { Contract.Assert(foreignKey.IsUnique); if (newValue != null) { SetForeignKeyValue(stateManager.GetOrCreateEntry(newValue), dependentProperties, entry, principalProperties); } if (oldValue != null) { ConditionallySetNullForeignKey(stateManager.GetOrCreateEntry(oldValue), dependentProperties, entry, principalProperties); } } if (oldValue != null) { ConditionallyClearInverse(entry, navigation, oldValue); } if (newValue != null) { SetInverse(entry, navigation, newValue); } }
private Sidecar CreateSidecar(StateEntry entry = null) { return new RelationshipsSnapshotFactory().Create(entry ?? CreateStateEntry()); }
public OriginalValues([NotNull] StateEntry stateEntry) : base(stateEntry, Check.NotNull(stateEntry, "stateEntry").EntityType.OriginalValueCount) { }
private void InitialFixup(StateEntry entry, EntityState oldState) { var entityType = entry.EntityType; foreach (var navigation in entityType.Navigations) { var navigationValue = entry[navigation]; if (navigationValue != null) { if (navigation.IsCollection()) { NavigationCollectionChangedAction( entry, navigation, ((IEnumerable)navigationValue).Cast <object>().ToList(), Enumerable.Empty <object>()); } else { NavigationReferenceChangedAction( entry, navigation, null, navigationValue); } } } var stateEntries = entry.StateManager.StateEntries.ToList(); // TODO: Perf on this state manager query foreach (var navigation in _model.Service.EntityTypes .SelectMany(e => e.Navigations) .Where(n => n.GetTargetType() == entityType)) { IClrCollectionAccessor collectionAccessor = null; if (navigation.IsCollection()) { collectionAccessor = _collectionAccessorSource.GetAccessor(navigation); } var navigationEntityType = navigation.EntityType; foreach (var relatedEntry in stateEntries) { if (relatedEntry.EntityType != navigationEntityType || relatedEntry == entry) { continue; } if (collectionAccessor != null) { if (collectionAccessor.Contains(relatedEntry.Entity, entry.Entity)) { NavigationCollectionChangedAction( relatedEntry, navigation, new[] { entry.Entity }, Enumerable.Empty <object>()); } } else { var navigationValue = relatedEntry[navigation]; if (navigationValue != null) { if (ReferenceEquals(navigationValue, entry.Entity)) { NavigationReferenceChangedAction( relatedEntry, navigation, null, navigationValue); } } } } } foreach (var foreignKey in entityType.ForeignKeys) { var principalEntry = entry.StateManager.GetPrincipal(entry.RelationshipsSnapshot, foreignKey); if (principalEntry != null) { DoFixup(foreignKey, principalEntry, new[] { entry }); } } foreach (var foreignKey in _model.Service.GetReferencingForeignKeys(entityType)) { var dependents = entry.StateManager.GetDependents(entry, foreignKey).ToArray(); if (dependents.Length > 0) { DoFixup(foreignKey, entry, dependents); } } }
private EntityKey CreateKey(IEntityType entityType, IReadOnlyList <IProperty> properties, StateEntry entry) { return(_keyFactorySource.GetKeyFactory(properties).Create(entityType, properties, entry)); }
private void DoFixup(IForeignKey foreignKey, StateEntry principalEntry, StateEntry[] dependentEntries) { DoFixup(_model.Service.GetNavigations(foreignKey).ToList(), principalEntry, dependentEntries); }
public override EntityKey Create(IEntityType entityType, IReadOnlyList <IProperty> properties, StateEntry entry) { Check.NotNull(entityType, "entityType"); Check.NotNull(properties, "properties"); Check.NotNull(entry, "entry"); // TODO: What happens if we get a null property value? return(new SimpleEntityKey <TKey>(entityType, (TKey)entry[properties[0]])); }
private void ConditionallyClearInverse(StateEntry entry, INavigation navigation, object entity) { var inverse = navigation.TryGetInverse(); if (inverse != null) { if (inverse.IsCollection()) { _collectionAccessorSource.GetAccessor(inverse).Remove(entity, entry.Entity); } else { if (ReferenceEquals(_getterSource.GetAccessor(inverse).GetClrValue(entity), entry.Entity)) { _setterSource.GetAccessor(inverse).SetClrValue(entity, null); } } _configuration.StateManager.GetOrCreateEntry(entity).RelationshipsSnapshot.TakeSnapshot(inverse); } }
public virtual Sidecar CreateOriginalValues([NotNull] StateEntry stateEntry) { Check.NotNull(stateEntry, "stateEntry"); return(_originalValuesFactory.Create(stateEntry)); }
private void Unfixup(IEnumerable <INavigation> navigations, StateEntry oldPrincipalEntry, StateEntry dependentEntry) { foreach (var navigation in navigations) { Unfixup(navigation, oldPrincipalEntry, dependentEntry); oldPrincipalEntry.RelationshipsSnapshot.TakeSnapshot(navigation); } }
public void StateChanging(StateEntry entry, EntityState newState) { }
private void SetInverse(StateEntry entry, INavigation navigation, object entity) { var inverse = navigation.TryGetInverse(); if (inverse != null) { if (inverse.IsCollection()) { var collectionAccessor = _collectionAccessorSource.GetAccessor(inverse); if (!collectionAccessor.Contains(entity, entry.Entity)) { collectionAccessor.Add(entity, entry.Entity); } } else { _setterSource.GetAccessor(inverse).SetClrValue(entity, entry.Entity); } _configuration.StateManager.GetOrCreateEntry(entity).RelationshipsSnapshot.TakeSnapshot(inverse); } }
public void ForeignKeyPropertyChanged(StateEntry entry, IProperty property, object oldValue, object newValue) { }
private static void ConditionallySetNullForeignKey( StateEntry dependentEntry, IReadOnlyList <IProperty> dependentProperties, StateEntry principalEntry, IReadOnlyList <IProperty> principalProperties) { ConditionallySetNullForeignKey(dependentEntry, dependentProperties, principalProperties.Select(p => principalEntry[p]).ToList()); }
public virtual void NavigationCollectionChanged(StateEntry entry, INavigation navigation, ISet<object> added, ISet<object> removed) { }
private static void SetNullForeignKey(StateEntry dependentEntry, IReadOnlyList<IProperty> dependentProperties) { foreach (var dependentProperty in dependentProperties) { // TODO: Conceptual nulls dependentEntry[dependentProperty] = null; dependentEntry.RelationshipsSnapshot.TakeSnapshot(dependentProperty); } }
public virtual void StateChanging(StateEntry entry, EntityState newState) { }
protected Sidecar([NotNull] StateEntry stateEntry) { Check.NotNull(stateEntry, "stateEntry"); _stateEntry = stateEntry; }
public RelationshipsSnapshot([NotNull] StateEntry stateEntry) : base(stateEntry, GetProperties(Check.NotNull(stateEntry, "stateEntry"))) { }
protected override Sidecar CreateSidecar(StateEntry entry = null) { return new OriginalValuesFactory().Create(entry ?? CreateStateEntry()); }