/// <summary> /// Invoked to update <see cref="VersionInfo"/>. /// </summary> /// <param name="changedEntity">The changed entity.</param> /// <param name="changedField">The changed field.</param> /// <returns> /// <see langword="True"/>, if <see cref="VersionInfo"/> was changed; /// otherwise, <see langword="false"/>. /// </returns> /// <exception cref="NotSupportedException">Version root can't implement /// <see cref="IHasVersionRoots"/>.</exception> protected internal bool UpdateVersionInfo(Entity changedEntity, FieldInfo changedField) { if (State.IsVersionInfoUpdated || IsRemoved || changedEntity.TypeInfo.IsSystem) { return(true); } bool changed = false; try { State.IsVersionInfoUpdated = true; // Prevents recursion if (!TypeInfo.HasVersionRoots) { changed = SystemUpdateVersionInfo(changedEntity, changedField); } else { foreach (var root in ((IHasVersionRoots)this).GetVersionRoots()) { if (root.TypeInfo.HasVersionRoots) { throw new NotSupportedException(Strings.ExVersionRootObjectCantImplementIHasVersionRoots); } changed |= root.UpdateVersionInfo(changedEntity, changedField); } } return(changed); } finally { State.IsVersionInfoUpdated = changed; } }
/// <exception cref="ArgumentException"><paramref name="field"/> belongs to a different type.</exception> internal PersistentFieldState GetFieldState(FieldInfo field) { if (field.ReflectedType.IsInterface) { field = TypeInfo.FieldMap[field]; } if (field.ReflectedType != TypeInfo) { throw new ArgumentException(Strings.ExFieldBelongsToADifferentType, "field"); } var mappingInfo = field.MappingInfo; if (mappingInfo.Length == 0) { return(0); // EntitySet or another proxy } PersistentFieldState state = 0; var tuple = Tuple; if (tuple != null && tuple.AreAllColumnsAvalilable(mappingInfo)) { state = PersistentFieldState.Loaded; } var diffTuple = tuple as DifferentialTuple; if (diffTuple != null && diffTuple.Difference.IsAtLeastOneColumAvailable(mappingInfo)) { state = PersistentFieldState.Modified; } return(state); }
protected override bool UpdateVersion(Entity changedEntity, M.FieldInfo changedField) { VersionId = new VersionStructure { Version = VersionId.Version + 1 }; return(true); }
internal override sealed void EnsureIsFetched(FieldInfo field) { var state = State; if (state.PersistenceState == PersistenceState.New) { return; } var tuple = state.Tuple; // tuple is already cleared if (tuple == null && (Session.Configuration.Options & SessionOptions.ReadRemovedObjects) == SessionOptions.ReadRemovedObjects) { return; } if (tuple.GetFieldState(field.MappingInfo.Offset).IsAvailable()) { return; } EnsureNotRemoved(); Session.Handler.FetchField(Key, field); }
private ColumnInfo BuildInheritedColumn(FieldInfo field, ColumnInfo ancestor) { var column = ancestor.Clone(); column.Field = field; column.Name = context.NameBuilder.BuildColumnName(field, ancestor); column.IsDeclared = field.IsDeclared; column.IsPrimaryKey = field.IsPrimaryKey; column.IsNullable = field.IsNullable; column.IsSystem = field.IsSystem; column.DefaultSqlExpression = field.DefaultSqlExpression; object defaultValue = null; if (field.IsEnum) { var underlyingType = Enum.GetUnderlyingType(field.ValueType.StripNullable()); if (field.DefaultValue != null) { defaultValue = Convert.ChangeType(field.DefaultValue, underlyingType); } } else { defaultValue = field.DefaultValue; } column.DefaultValue = defaultValue; return(column); }
internal override sealed void SystemBeforeGetValue(FieldInfo field) { if (!Session.Configuration.Supports(SessionOptions.ReadRemovedObjects)) { EnsureNotRemoved(); } if (Session.IsDebugEventLoggingEnabled) { OrmLog.Debug(Strings.LogSessionXGettingValueKeyYFieldZ, Session, Key, field); } EnsureIsFetched(field); Session.SystemEvents.NotifyFieldValueGetting(this, field); using (Session.Operations.EnableSystemOperationRegistration()) { Session.Events.NotifyFieldValueGetting(this, field); if (Session.IsSystemLogicOnly) { return; } var subscriptionInfo = GetSubscription(EntityEventBroker.GettingFieldEventKey); if (subscriptionInfo.Second != null) { ((Action <Key, FieldInfo>)subscriptionInfo.Second) .Invoke(subscriptionInfo.First, field); } OnGettingFieldValue(field); } }
/// <summary> /// Builds the name for the <see cref="AssociationInfo"/>. /// </summary> /// <param name="ownerType">Type of the owner.</param> /// <param name="ownerField">The owner field.</param> /// <param name="targetType">Type of the target.</param> /// <returns>Association name.</returns> public string BuildAssociationName(TypeInfo ownerType, FieldInfo ownerField, TypeInfo targetType) { return(ApplyNamingRules(string.Format(AssociationPattern, ownerType.Name, ownerField.Name, targetType.Name))); }
public override void TestFixtureSetUp() { base.TestFixtureSetUp(); CustomerType = Domain.Model.Types[typeof(Customer)]; OrderType = Domain.Model.Types[typeof(Order)]; ProductType = Domain.Model.Types[typeof(Product)]; BookType = Domain.Model.Types[typeof(Book)]; TitleType = Domain.Model.Types[typeof(Title)]; ITitleType = Domain.Model.Types[typeof(ITitle)]; OfferContainerType = Domain.Model.Types[typeof(OfferContainer)]; PersonIdField = Domain.Model.Types[typeof(Person)].Fields["Id"]; OrderIdField = Domain.Model.Types[typeof(Order)].Fields["Id"]; CityField = CustomerType.Fields["City"]; AgeField = Domain.Model.Types[typeof(AdvancedPerson)].Fields["Age"]; CustomerField = OrderType.Fields["Customer"]; EmployeeField = OrderType.Fields["Employee"]; DetailsField = OrderType.Fields["Details"]; BooksField = Domain.Model.Types[typeof(Author)].Fields["Books"]; BookTitleField = BookType.Fields["Title"]; TitleBookField = TitleType.Fields["Book"]; LanguageField = TitleType.Fields["Language"]; TextField = TitleType.Fields["Text"]; GraphContainersField = typeof(PrefetchManager).GetField("graphContainers", BindingFlags.NonPublic | BindingFlags.Instance); PrefetchProcessorField = typeof(SqlSessionHandler).GetField("prefetchManager", BindingFlags.NonPublic | BindingFlags.Instance); PrefetchTestHelper.FillDataBase(Domain); }
internal override sealed void SystemSetValue(FieldInfo field, object oldValue, object newValue) { Session.SystemEvents.NotifyFieldValueSet(this, field, oldValue, newValue); using (Session.Operations.EnableSystemOperationRegistration()) { Session.Events.NotifyFieldValueSet(this, field, oldValue, newValue); if (Session.IsSystemLogicOnly) { return; } if (CanBeValidated) { Session.ValidationContext.RegisterForValidation(this, field); } var subscriptionInfo = GetSubscription(EntityEventBroker.SetFieldEventKey); if (subscriptionInfo.Second != null) { ((Action <Key, FieldInfo, object, object>)subscriptionInfo.Second) .Invoke(subscriptionInfo.First, field, oldValue, newValue); } NotifyFieldChanged(field); OnSetFieldValue(field, oldValue, newValue); } }
internal override sealed void SystemSetValueCompleted(FieldInfo field, object oldValue, object newValue, Exception exception) { Session.SystemEvents.NotifyFieldValueSetCompleted(this, field, oldValue, newValue, exception); using (Session.Operations.EnableSystemOperationRegistration()) { Session.Events.NotifyFieldValueSetCompleted(this, field, oldValue, newValue, exception); } }
internal override sealed void SystemBeforeSetValue(FieldInfo field, object value) { EnsureNotRemoved(); if (!changeVersionOnSetAttempt) { UpdateVersionInfo(this, field); } Session.SystemEvents.NotifyFieldValueSetting(this, field, value); using (Session.Operations.EnableSystemOperationRegistration()) { Session.Events.NotifyFieldValueSetting(this, field, value); if (Session.IsSystemLogicOnly) { return; } var subscriptionInfo = GetSubscription(EntityEventBroker.SettingFieldEventKey); if (subscriptionInfo.Second != null) { ((Action <Key, FieldInfo, object>)subscriptionInfo.Second).Invoke(subscriptionInfo.First, field, value); } OnSettingFieldValue(field, value); } }
internal override sealed void SystemSetValueAttempt(FieldInfo field, object value) { EnsureNotRemoved(); OrmLog.Debug(Strings.LogSessionXSettingValueKeyYFieldZ, Session, Key, field); if (field.IsPrimaryKey) { throw new NotSupportedException(string.Format(Strings.ExUnableToSetKeyFieldXExplicitly, field.Name)); } if (changeVersionOnSetAttempt) { UpdateVersionInfo(this, field); } Session.SystemEvents.NotifyFieldValueSettingAttempt(this, field, value); using (Session.Operations.EnableSystemOperationRegistration()) { Session.Events.NotifyFieldValueSettingAttempt(this, field, value); if (Session.IsSystemLogicOnly) { return; } var subscriptionInfo = GetSubscription(EntityEventBroker.SettingFieldAttemptEventKey); if (subscriptionInfo.Second != null) { ((Action <Key, FieldInfo, object>)subscriptionInfo.Second).Invoke(subscriptionInfo.First, field, value); } OnSettingFieldValueAttempt(field, value); Session.ValidationContext.ValidateSetAttempt(this, field, value); } }
internal override sealed void SystemBeforeGetValue(FieldInfo field) { if (!Session.Configuration.Supports(SessionOptions.ReadRemovedObjects)) { EnsureNotRemoved(); } // getting of field value is frequent operation and access to resources // will slow down execution significantly if (OrmLog.IsLogged(LogLevel.Debug)) { OrmLog.Debug(Strings.LogSessionXGettingValueKeyYFieldZ, Session, Key, field); } EnsureIsFetched(field); Session.SystemEvents.NotifyFieldValueGetting(this, field); using (Session.Operations.EnableSystemOperationRegistration()) { Session.Events.NotifyFieldValueGetting(this, field); if (Session.IsSystemLogicOnly) { return; } var subscriptionInfo = GetSubscription(EntityEventBroker.GettingFieldEventKey); if (subscriptionInfo.Second != null) { ((Action <Key, FieldInfo>)subscriptionInfo.Second) .Invoke(subscriptionInfo.First, field); } OnGettingFieldValue(field); } }
/// <summary> /// Builds foreign key name by association. /// </summary> /// <returns>Foreign key name.</returns> public string BuildReferenceForeignKeyName(TypeInfo ownerType, FieldInfo ownerField, TypeInfo targetType) { ArgumentValidator.EnsureArgumentNotNull(ownerType, "ownerType"); ArgumentValidator.EnsureArgumentNotNull(ownerField, "ownerField"); ArgumentValidator.EnsureArgumentNotNull(targetType, "targetType"); return(ApplyNamingRules(string.Format(ReferenceForeignKeyFormat, ownerType.Name, ownerField.Name, targetType.Name))); }
// Constructors /// <summary> /// Initializes a new instance of this class. /// </summary> /// <param name="owner">Persistent this entity set belongs to.</param> /// <param name="field">Field corresponds to this entity set.</param> protected EntitySetBase(Entity owner, FieldInfo field) : base(owner.Session) { this.owner = owner; Field = field; State = new EntitySetState(this); var association = Field.Associations.Last(); if (association.AuxiliaryType != null && association.IsMaster) { Domain domain = Session.Domain; var itemType = domain.Model.Types[Field.ItemType]; auxilaryTypeKeyTransform = new CombineTransform( false, owner.TypeInfo.Key.TupleDescriptor, itemType.Key.TupleDescriptor); } if (association.Multiplicity != Multiplicity.ManyToOne && association.Multiplicity != Multiplicity.OneToMany) { skipOwnerVersionChange = false; } else { skipOwnerVersionChange = Session.Domain.Configuration.VersioningConvention.DenyEntitySetOwnerVersionChange; } Initialize(WellKnownOrmTypes.EntitySetBase); }
protected bool IsFieldAvailable(FieldInfo field) { if (field.ReflectedType.IsInterface) { field = TypeInfo.FieldMap[field]; } return(Tuple.GetFieldState(field.MappingInfo.Offset).IsAvailable()); }
internal FieldAccessor <T> GetFieldAccessor <T>(FieldInfo field) { if (field.ReflectedType.IsInterface) { field = TypeInfo.FieldMap[field]; } return((FieldAccessor <T>)field.ReflectedType.Accessors.GetFieldAccessor(field)); }
/// <summary> /// Called to update the fields describing <see cref="Entity"/>'s version. /// </summary> /// <param name="changedEntity">The changed entity.</param> /// <param name="changedField">The changed field.</param> /// <returns> /// <see langword="True"/>, if <see cref="VersionInfo"/> was changed; /// otherwise, <see langword="false"/>. /// </returns> protected virtual bool UpdateVersion(Entity changedEntity, FieldInfo changedField) { foreach (var field in TypeInfo.GetVersionFields().Where(f => f.AutoVersion)) { SetFieldValue(field, VersionGenerator.GenerateNextVersion(GetFieldValue(field))); } return(true); }
/// <summary> /// Sets the field value. /// Field value type must be specified precisely. /// E.g. usage of <see cref="Object"/> instead of <see cref="IEntity"/> might lead to unpredictable effects. /// </summary> /// <typeparam name="T">Field value type.</typeparam> /// <param name="field">The field.</param> /// <param name="value">The value to set.</param> protected internal void SetFieldValue <T>(FieldInfo field, T value) { if (field.ReflectedType.IsInterface) { field = TypeInfo.FieldMap[field]; } SetFieldValue(field, (object)value); }
/// <summary> /// Gets the name for <see cref="ColumnInfo"/> object. /// </summary> /// <param name="field">The field info.</param> /// <param name="baseColumn">The <see cref="ColumnInfo"/> object.</param> /// <returns>Column name.</returns> public string BuildColumnName(FieldInfo field, ColumnInfo baseColumn) { ArgumentValidator.EnsureArgumentNotNull(field, "field"); ArgumentValidator.EnsureArgumentNotNull(baseColumn, "baseColumn"); var result = field.MappingName ?? field.Name; return(ApplyNamingRules(result)); }
internal static void ValidateLoadedEntitySet(Key key, FieldInfo field, int count, bool isFullyLoaded, Session session) { EntitySetState state; Assert.IsTrue(session.Handler.LookupState(key, field, out state)); Assert.AreEqual(count, state.Count()); Assert.AreEqual(isFullyLoaded, state.IsFullyLoaded); }
private static Expression BuildExpressionForFieldRecursivly(FieldInfo field, Expression parameter) { if (field.IsNested) { var expression = BuildExpressionForFieldRecursivly(field.Parent, parameter); return(Expression.Property(expression, field.DeclaringField.UnderlyingProperty)); } return(Expression.Property(parameter, field.DeclaringField.UnderlyingProperty)); }
private void BuildNestedFields(FieldInfo source, FieldInfo target, IEnumerable<FieldInfo> fields) { var buffer = fields.ToList(); foreach (var field in buffer) { var clone = field.Clone(); if (target.SkipVersion) clone.SkipVersion = true; clone.IsSystem = false; clone.IsLazyLoad = field.IsLazyLoad || target.IsLazyLoad; if (target.IsDeclared) { clone.Name = context.NameBuilder.BuildNestedFieldName(target, field); clone.OriginalName = field.OriginalName; // One-field reference if (target.IsEntity && buffer.Count == 1) { clone.MappingName = target.MappingName; clone.DefaultValue = target.DefaultValue; } else clone.MappingName = context.NameBuilder.BuildMappingName(target, field); } if (target.Fields.Contains(clone.Name)) continue; clone.Parent = target; target.ReflectedType.Fields.Add(clone); if (field.IsStructure || field.IsEntity) { BuildNestedFields(source, clone, field.Fields); foreach (FieldInfo clonedFields in clone.Fields) target.Fields.Add(clonedFields); } else { if (field.Column!=null) clone.Column = BuildInheritedColumn(clone, field.Column); } if (target.IsStructure && clone.IsEntity && !IsAuxiliaryType(clone.ReflectedType)) { var origin = context.Model.Associations .Find(context.Model.Types[field.ValueType], true) .FirstOrDefault(a => a.OwnerField.Equals(field)); if (origin!=null && !clone.IsInherited) { AssociationBuilder.BuildAssociation(context, origin, clone); context.DiscardedAssociations.Add(origin); } } if (!clone.IsStructure && !clone.IsEntitySet && !target.ReflectedType.IsInterface && 0!=(clone.Attributes & FieldAttributes.Indexed)) { var typeDef = context.ModelDef.Types[target.DeclaringType.UnderlyingType]; var attribute = new IndexAttribute(clone.Name); var index = context.ModelDefBuilder.DefineIndex(typeDef, attribute); if (typeDef.Indexes.Contains(index.Name)) throw new DomainBuilderException( string.Format(Strings.ExIndexWithNameXIsAlreadyRegistered, index.Name)); typeDef.Indexes.Add(index); BuildLog.Info(Strings.LogIndexX, index.Name); } } }
// Constructors public CacheKey(FieldInfo referencingField, int?itemCountLimit) { this.ReferencingField = referencingField; this.ItemCountLimit = itemCountLimit; unchecked { cachedHashCode = (ReferencingField.GetHashCode() * 397) ^ (ItemCountLimit.HasValue ? 1 : 0); } }
private Expression BuildFieldAccess(FieldInfo field, bool addNullability) { var fieldIndex = usedFields.Count; var valueType = addNullability ? field.ValueType.ToNullable() : field.ValueType; usedFields.Add(field); return(Expression.Call(parameter, WellKnownMembers.Tuple.GenericAccessor.MakeGenericMethod(valueType), Expression.Constant(fieldIndex))); }
private static FieldAccessor CreateFieldAccessor(Type accessorType, FieldInfo field) { var accessor = (FieldAccessor) System.Activator.CreateInstance( accessorType.MakeGenericType(field.ValueType), BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, ArrayUtils <object> .EmptyArray, null); accessor.Field = field; return(accessor); }
private void EnsureCanBeUsedInFilter(Expression expression, FieldInfo field) { var canBeUsed = field.ReflectedType == field.DeclaringType || field.IsPrimaryKey || field.DeclaringType.Hierarchy.InheritanceSchema != InheritanceSchema.ClassTable; if (!canBeUsed) { throw UnableToTranslate(expression, string.Format(Strings.FieldXDoesNotExistInTableForY, field.Name, field.ReflectedType)); } }
/// <summary> /// Gets the key of the entity, that is referenced by specified field /// of the target persistent object. /// </summary> /// <remarks> /// Result is the same as <c>GetValue<Entity>(field).Key</c>, /// but referenced entity will not be materialized. /// </remarks> /// <param name="field">The reference field. Field value type must be /// <see cref="Entity"/> descendant.</param> /// <returns>Referenced entity key.</returns> /// <exception cref="InvalidOperationException">Field is not a reference field.</exception> protected internal Key GetReferenceKey(FieldInfo field) { Key key = null; try { if (field.ReflectedType.IsInterface) { field = TypeInfo.FieldMap[field]; } SystemBeforeGetValue(field); if (!field.IsEntity) { throw new InvalidOperationException( String.Format(Strings.ExFieldIsNotAnEntityField, field.Name, field.ReflectedType.Name)); } var types = Session.Domain.Model.Types; var type = types[field.ValueType]; var tuple = Tuple; if (tuple.ContainsEmptyValues(field.MappingInfo)) { return(null); } int typeIdColumnIndex = type.Key.TypeIdColumnIndex; var accuracy = TypeReferenceAccuracy.BaseType; if (typeIdColumnIndex >= 0) { accuracy = TypeReferenceAccuracy.ExactType; } var keyValue = field.ExtractValue(tuple); if (accuracy == TypeReferenceAccuracy.ExactType) { int typeId = keyValue.GetValueOrDefault <int>(typeIdColumnIndex); if (typeId != TypeInfo.NoTypeId) // != default(int) != 0 { type = types[typeId]; } else { // This may happen if reference is null accuracy = TypeReferenceAccuracy.BaseType; } } key = Key.Create(Session.Domain, Session.StorageNodeId, type, accuracy, keyValue); SystemGetValue(field, key); SystemGetValueCompleted(field, key, null); return(key); } catch (Exception e) { SystemGetValueCompleted(field, key, e); throw; } }
/// <summary> /// Builds the <see cref="MappedNode.MappingName"/>. /// </summary> /// <param name="complexField">The complex field.</param> /// <param name="childField">The child field.</param> /// <returns>Field mapping name.</returns> public string BuildMappingName(FieldInfo complexField, FieldInfo childField) { Func <FieldInfo, string> getMappingName = f => f.MappingName ?? f.Name; var nameSource = complexField; while (nameSource.Parent != null) { nameSource = nameSource.Parent; } return(string.Concat(getMappingName(nameSource), ".", getMappingName(childField))); }
/// <summary> /// Builds the full name of the <paramref name="childField"/>. /// </summary> /// <param name="complexField">The complex field.</param> /// <param name="childField">The child field.</param> /// <returns>Nested field name.</returns> public string BuildNestedFieldName(FieldInfo complexField, FieldInfo childField) { ArgumentValidator.EnsureArgumentNotNull(complexField, "complexField"); ArgumentValidator.EnsureArgumentNotNull(childField, "childField"); var nameSource = complexField; while (nameSource.Parent != null) { nameSource = nameSource.Parent; } return(string.Concat(nameSource.Name, ".", childField.Name)); }