Пример #1
0
        /// <summary>Registers DB sequences. </summary>
        /// <param name="name">Sequence name.</param>
        /// <param name="type">Data type, optional. If null, 64-bit integer is assumed.</param>
        /// <param name="startValue">Optional, assumed zero if missing.</param>
        /// <param name="increment">Optional, assumed 1 if missing.</param>
        /// <param name="explicitSchema">Optional, explicit schema. If missing, sequence schema is assigned from module's area.</param>
        public void RegisterSequence(string name, Type type = null, int startValue = 0, int increment = 1, string explicitSchema = null)
        {
            type = type ?? typeof(long);
            var sequence = new SequenceDefinition(this, name, type, startValue, increment, explicitSchema);

            Sequences.Add(sequence);
        }
Пример #2
0
        public static T GetSequenceNextValue <T>(this IEntitySession session, SequenceDefinition sequence)
            where T : struct
        {
            Util.Check(sequence != null, "Sequence parameter may not be null.");
            Util.Check(typeof(T) == sequence.DataType, "Requested next value type {0} does not match sequence {1} data type (2}.",
                       typeof(T), sequence.Name, sequence.DataType);
            var ds         = session.Context.App.DataAccess.GetDataSource(session.Context);
            var db         = ds.Database;
            var entSession = (EntitySession)session;
            var v          = db.GetSequenceNextValue(entSession, sequence);

            if (v.GetType() == typeof(T))
            {
                return((T)v);
            }
            //Postgres - all sequences are int64, so we need to convert here
            return((T)ConvertHelper.ChangeType(v, typeof(T)));
        }
Пример #3
0
        public override void ApplyOnMember(EntityModelBuilder builder)
        {
            HostMember.Flags        |= EntityMemberFlags.AutoValue;
            HostMember.AutoValueType = this.Type;
            switch (this.Type)
            {
            case AutoType.Identity:
                HostEntity.Flags         |= EntityFlags.HasIdentity;
                HostEntity.IdentityMember = HostMember;
                base.HostMember.Flags    |= EntityMemberFlags.Identity | EntityMemberFlags.NoDbInsert | EntityMemberFlags.NoDbUpdate;
                //Usually identity is int (or long). But there are some wierd real-life databases with Numeric (Decimal) identity columns
                // apparently MS SQL allows this
                var intOrDec = base.HostMember.DataType.IsInt() || base.HostMember.DataType == typeof(Decimal);
                if (!intOrDec)
                {
                    builder.Log.Error("Entity member {0}.{1}, type {2}: Identity attribute may be set only on member of integer or decimal types. ",
                                      HostEntity, base.HostMember.MemberName, this.Type);
                    return;
                }
                HostEntity.Events.New += EntityEvent_NewEntityHandleIdentity;
                HostEntity.SaveEvents.SubmittedChanges += EntityEvent_IdentityEntitySubmitted;
                break;

            case AutoType.Sequence:
                if (!base.HostMember.DataType.IsInt())
                {
                    builder.Log.Error("Entity member {0}.{1}, type {2}: Sequence attribute may be set only on member of integer types. ",
                                      HostEntity, HostMember.MemberName, this.Type);
                    return;
                }
                if (string.IsNullOrWhiteSpace(this.SequenceName))
                {
                    builder.Log.Error("Entity member {0}.{1}: Sequence name must be specified.", HostEntity, HostMember.MemberName);
                    return;
                }
                _sequence = builder.Model.FindSequence(this.SequenceName, HostEntity.Module);
                if (_sequence == null)
                {
                    builder.Log.Error("Entity member {0}.{1}: Sequence {0} not defined.",
                                      HostEntity, HostMember.MemberName, this.SequenceName);
                    return;
                }
                if (_sequence.DataType != base.HostMember.DataType)
                {
                    builder.Log.Error("Entity member {0}.{1}: data type {2} does not match sequence '{3}' data type {4}.",
                                      HostEntity, HostMember.MemberName, HostMember.DataType, this.SequenceName, _sequence.DataType);
                    return;
                }
                HostEntity.Events.New += EntityEvent_NewEntityHandleSequence;
                break;

            case AutoType.NewGuid:
                if (!CheckDataType(builder, typeof(Guid)))
                {
                    builder.Log.Error("Entity member {0}.{1}: Auto attribute with AutoType=NewGuid must be on Guid-type member.",
                                      HostEntity, HostMember.MemberName);
                    return;
                }
                HostEntity.Events.New += EntityEvent_HandleNewGuid;
                break;

            case AutoType.CreatedOn:
            case AutoType.UpdatedOn:
                if (!CheckDataType(builder, typeof(DateTime), typeof(DateTime?)))
                {
                    return;
                }
                if (this.Type == AutoType.CreatedOn)
                {
                    base.HostMember.Flags |= EntityMemberFlags.NoDbUpdate;
                }
                HostEntity.SaveEvents.SavingChanges += EntityEvent_HandleCreatedUpdatedOnDateTime;
                break;

            case AutoType.CreatedBy:
                if (!CheckDataType(builder, typeof(string)))
                {
                    return;
                }
                HostEntity.Events.New += EntityEvent_HandleUpdatedCreatedBy;
                base.HostMember.Flags |= EntityMemberFlags.NoDbUpdate;
                break;

            case AutoType.UpdatedBy:
                if (!CheckDataType(builder, typeof(string)))
                {
                    return;
                }
                HostEntity.Events.New      += EntityEvent_HandleUpdatedCreatedBy;
                HostEntity.Events.Modified += EntityEvent_HandleUpdatedCreatedBy;
                break;

            case AutoType.CreatedById:
                if (!CheckDataType(builder, typeof(Guid), typeof(int)))
                {
                    return;
                }
                HostEntity.Events.New += EntityEvent_HandleUpdatedCreatedById;
                base.HostMember.Flags |= EntityMemberFlags.NoDbUpdate;
                break;

            case AutoType.UpdatedById:
                if (!CheckDataType(builder, typeof(Guid), typeof(int)))
                {
                    return;
                }
                HostEntity.Events.New      += EntityEvent_HandleUpdatedCreatedById;
                HostEntity.Events.Modified += EntityEvent_HandleUpdatedCreatedById;
                break;

            case AutoType.TransIdCreated:
                if (!CheckDataType(builder, typeof(Guid)))
                {
                    return;
                }
                HostEntity.Events.New += HandleCreatedUpdatedInTransId;
                HostMember.Flags      |= EntityMemberFlags.NoDbUpdate;
                break;

            case AutoType.TransIdUpdated:
                if (!CheckDataType(builder, typeof(Guid)))
                {
                    return;
                }
                HostEntity.Events.New      += HandleCreatedUpdatedInTransId;
                HostEntity.Events.Modified += HandleCreatedUpdatedInTransId;
                break;

            case AutoType.RowVersion:
                HostEntity.RowVersionMember        = base.HostMember;
                base.HostMember.Flags             |= EntityMemberFlags.RowVersion | EntityMemberFlags.NoDbInsert | EntityMemberFlags.NoDbUpdate;
                base.HostEntity.Flags             |= EntityFlags.HasRowVersion;
                base.HostMember.ExplicitDbTypeSpec = "rowversion";
                break;
            }//swith AutoValueType
        }
Пример #4
0
        public override void Apply(AttributeContext context, Attribute attribute, EntityMemberInfo member)
        {
            _member = member;
            var entity = member.Entity;

            member.Flags        |= EntityMemberFlags.AutoValue;
            member.AutoValueType = this.Type;
            switch (this.Type)
            {
            case AutoType.Identity:
                entity.Flags |= EntityFlags.HasIdentity;
                member.Flags |= EntityMemberFlags.Identity | EntityMemberFlags.NoDbInsert | EntityMemberFlags.NoDbUpdate;
                //Usually identity is int (or long). But there are some wierd real-life databases with Numeric (Decimal) identity columns
                // apparently MS SQL allows this
                var intOrDec = member.DataType.IsInt() || member.DataType == typeof(Decimal);
                if (!intOrDec)
                {
                    context.Log.Error("Entity member {0}.{1}, type {2}: Identity attribute may be set only on member of integer or decimal types. ",
                                      _member.Entity, _member.MemberName, this.Type);
                    return;
                }
                entity.Events.New += EntityEvent_NewEntityHandleIdentity;
                // Mark all entities referencing This entity with ReferencesIdentity flag
                foreach (var mr in entity.IncomingReferences)
                {
                    mr.Entity.Flags |= EntityFlags.ReferencesIdentity;
                }
                break;

            case AutoType.Sequence:
                if (!member.DataType.IsInt())
                {
                    context.Log.Error("Entity member {0}.{1}, type {2}: Sequence attribute may be set only on member of integer types. ",
                                      _member.Entity, _member.MemberName, this.Type);
                    return;
                }
                if (string.IsNullOrWhiteSpace(SequenceName))
                {
                    context.Log.Error("Entity member {0}.{1}: Sequence name must be specified.", _member.Entity, _member.MemberName);
                    return;
                }
                _sequence = context.Model.FindSequence(SequenceName, entity.Module);
                if (_sequence == null)
                {
                    context.Log.Error("Entity member {0}.{1}: Sequence {0} not defined.", _member.Entity, _member.MemberName, this.SequenceName);
                    return;
                }
                if (_sequence.DataType != member.DataType)
                {
                    context.Log.Error("Entity member {0}.{1}: data type {2} does not match sequence '{3}' data type {4}.", _member.Entity, _member.MemberName, _member.DataType, this.SequenceName, _sequence.DataType);
                    return;
                }
                entity.Events.New += EntityEvent_NewEntityHandleSequence;
                break;

            case AutoType.NewGuid:
                if (!CheckDataType(context, typeof(Guid)))
                {
                    return;
                }
                entity.Events.New += EntityEvent_HandleNewGuid;
                break;

            case AutoType.CreatedOn:
            case AutoType.UpdatedOn:
                if (!CheckDataType(context, typeof(DateTime), typeof(DateTimeOffset)))
                {
                    return;
                }
                if (this.Type == AutoType.CreatedOn)
                {
                    member.Flags |= EntityMemberFlags.NoDbUpdate;
                }
                if (member.DataType == typeof(DateTime) || member.DataType == typeof(DateTime?))
                {
                    entity.SaveEvents.SavingChanges += EntityEvent_HandleCreatedUpdatedOnDateTime;
                }
                else
                {
                    entity.SaveEvents.SavingChanges += EntityEvent_HandleCreatedUpdatedOnDateTimeOffset;
                }
                break;

            case AutoType.CreatedBy:
                if (!CheckDataType(context, typeof(string)))
                {
                    return;
                }
                entity.Events.New += EntityEvent_HandleUpdatedCreatedBy;
                member.Flags      |= EntityMemberFlags.NoDbUpdate;
                break;

            case AutoType.UpdatedBy:
                if (!CheckDataType(context, typeof(string)))
                {
                    return;
                }
                entity.Events.New      += EntityEvent_HandleUpdatedCreatedBy;
                entity.Events.Modified += EntityEvent_HandleUpdatedCreatedBy;
                break;

            case AutoType.CreatedById:
                entity.Events.New += EntityEvent_HandleUpdatedCreatedById;
                member.Flags      |= EntityMemberFlags.NoDbUpdate;
                break;

            case AutoType.UpdatedById:
                entity.Events.New      += EntityEvent_HandleUpdatedCreatedById;
                entity.Events.Modified += EntityEvent_HandleUpdatedCreatedById;
                break;

            case AutoType.RowVersion:
                member.Flags             |= EntityMemberFlags.RowVersion | EntityMemberFlags.NoDbInsert | EntityMemberFlags.NoDbUpdate;
                member.Entity.Flags      |= EntityFlags.HasRowVersion;
                member.ExplicitDbTypeSpec = "timestamp";
                break;
            }//swith AutoValueType
        }
Пример #5
0
 public static long GetSequenceNextValue(this IEntitySession session, SequenceDefinition sequence)
 {
     return(session.Select(() => sequence.NextValue()));
 }
Пример #6
0
 public static long NextValue(this SequenceDefinition sequence)
 {
     Util.Throw("Function may not be called directly, only referenced in LINQ expressions.");
     return(0); // never happens
 }