public void AddField(string fieldName, System.Data.DbType fieldType, int length, bool isPrimaryKey, bool requireUnique, FieldOrder searchOrder)
 {
     if (this.Registered & !this.AllowRuntimeChanges) throw new InvalidOperationException("The Entity is already registered, it cannot be modified");
     if (this.Registered & isPrimaryKey) throw new ArgumentException("The Entity is already registered, you cannot add a primary key", "isPrimaryKey");
     var attr = new FieldAttribute();
     attr.FieldName = fieldName;
     attr.DataType = fieldType;
     attr.AllowsNulls = !isPrimaryKey;
     attr.IsPrimaryKey = isPrimaryKey;
     attr.IsIdentity = EntityAttribute.KeyScheme == KeyScheme.Identity & isPrimaryKey & this.Fields.KeyFields.Count <= 0;
     attr.Length = length;
     attr.RequireUniqueValue = requireUnique;
     attr.SearchOrder = searchOrder;
     this.Fields.Add(attr);
     if (this.Registered && EntityDefinitionChanged != null)
         EntityDefinitionChanged.Invoke(this, new EntityTypeChangedArgs(this, attr));
 }
예제 #2
0
 protected void AddField(FieldAttribute field)
 {
     Fields.Add(field);
 }
예제 #3
0
 internal EntityTypeChangedArgs(EntityInfo info, FieldAttribute field)
 {
     EntityInfo = info;
     ReferenceAttribute = null;
     FieldAttribute = field;
     TableCreated = false;
 }
예제 #4
0
 protected void AddFieldToEntity(EntityInfo entity, FieldAttribute field)
 {
     entity.Fields.Add(field);
 }
예제 #5
0
        public override DynamicEntityDefinition DiscoverDynamicEntity(string entityName)
        {
            if (!TableExists(entityName))
            {
                throw new EntityNotFoundException(entityName);
            }

            var connection = GetConnection(true);

            try
            {
                using (var cmd = GetNewCommandObject())
                {
                    cmd.Connection  = connection;
                    cmd.Transaction = CurrentTransaction;

                    cmd.CommandText = string.Format("SELECT COLUMN_NAME, ORDINAL_POSITION, IS_NULLABLE, DATA_TYPE, NUMERIC_PRECISION, NUMERIC_SCALE FROM information_schema.columns WHERE TABLE_NAME = '{0}' ORDER BY ORDINAL_POSITION", entityName);

                    var fields = new List <FieldAttribute>();

                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var name     = reader.GetString(0);
                            var nullable = string.Compare(reader.GetString(2), "YES", true) == 0;
                            var type     = reader.GetString(3).ParseToDbType();

                            var field = new FieldAttribute()
                            {
                                DataType    = type,
                                FieldName   = name,
                                AllowsNulls = nullable,
                            };

                            if (!reader.IsDBNull(4))
                            {
                                field.Precision = Convert.ToInt32(reader.GetValue(4));
                            }
                            if (!reader.IsDBNull(5))
                            {
                                field.Scale = Convert.ToInt32(reader.GetValue(5));
                            }

                            fields.Add(field);
                        }
                    }

                    // get PK info
                    cmd.CommandText = string.Format(
                        "SELECT COLUMN_NAME, CONSTRAINT_TYPE " +
                        "FROM information_schema.table_constraints t " +
                        "LEFT JOIN information_schema.key_column_usage k " +
                        "USING(constraint_name,table_schema,table_name) " +
                        "WHERE TABLE_NAME = '{0}'", entityName);

                    // result will be PRIMARY_KEY or UNIQUE

                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var column = reader.GetString(0);
                            var t      = reader.GetString(1);

                            var pk     = t == "PRIMARY_KEY";
                            var unique = t == "UNIQUE";

                            var field = fields.FirstOrDefault(f => f.FieldName == column);
                            if (pk)
                            {
                                field.IsPrimaryKey = true;
                            }

                            if (unique)
                            {
                                field.RequireUniqueValue = true;
                            }
                        }
                    }


                    var entityDefinition = new DynamicEntityDefinition(entityName, fields);
                    RegisterEntityInfo(entityDefinition);
                    return(entityDefinition);
                }
            }
            finally
            {
                DoneWithConnection(connection, true);
            }
        }
        protected override string GetFieldCreationAttributes(EntityAttribute attribute, FieldAttribute field, Boolean MultiplePrimaryKeys)
        {
            StringBuilder sb = new StringBuilder();

            switch (field.DataType)
            {
            case DbType.AnsiString:
            case DbType.AnsiStringFixedLength:
            case DbType.StringFixedLength:
            case DbType.String:
                if (field.Length > 0)
                {
                    sb.AppendFormat("({0}) ", field.Length);
                }
                else
                {
                    sb.AppendFormat("({0}) ", DefaultStringFieldSize);
                }
                break;

            case DbType.Decimal:
                int p = field.Precision == 0 ? DefaultNumericFieldPrecision : field.Precision;
                sb.AppendFormat("({0},{1}) ", p, field.Scale);
                break;
            }

            if (field.Default != null && field.Default.Length > 0)
            {
                sb.AppendFormat("DEFAULT {0} ", field.Default);
            }

            if (field.IsPrimaryKey)
            {
                if (!MultiplePrimaryKeys)
                {
                    sb.Append("PRIMARY KEY ");
                }

                if (attribute.KeyScheme == KeyScheme.Identity)
                {
                    throw new NotImplementedException();
                    //switch (field.DataType)
                    //{
                    //    case DbType.Int32:
                    //    case DbType.UInt32:
                    //        sb.Append(AutoIncrementFieldIdentifier + " ");
                    //        break;
                    //    case DbType.Guid:
                    //        sb.Append("ROWGUIDCOL ");
                    //        break;
                    //    default:
                    //        throw new FieldDefinitionException(attribute.NameInStore, field.FieldName,
                    //            string.Format("Data Type '{0}' cannot be marked as an Identity field", field.DataType));
                    //}
                }
            }

            if (!field.AllowsNulls)
            {
                sb.Append("NOT NULL ");
            }

            if (field.RequireUniqueValue)
            {
                sb.Append("UNIQUE ");
            }

            return(sb.ToString());
        }
예제 #7
0
        protected override void Insert(object item, bool insertReferences, IDbConnection connection, IDbTransaction transaction, bool checkUpdates)
        {
            var    isDynamicEntity = item is DynamicEntity;
            string entityName      = null;

            if (isDynamicEntity)
            {
                entityName = ((DynamicEntity)item).EntityName;
                if (!m_entities.HasEntity(entityName))
                {
                    throw new EntityNotFoundException(entityName);
                }
            }
            else
            {
                entityName = m_entities.GetNameForType(item.GetType());
            }

            if (entityName == null)
            {
                throw new EntityNotFoundException(item.GetType());
            }
            var entity = m_entities[entityName];

            Boolean bInheritedConnection = connection != null;

            if (transaction == null && connection == null)
            {
                connection = GetConnection(false);
            }
            try
            {
                // CheckOrdinals(entityName);
                FieldAttribute identity = null;
                var            command  = GetInsertCommand(entityName);
                if (transaction == null)
                {
                    command.Connection = connection as FbConnection;
                }
                else
                {
                    command.Connection  = transaction.Connection as FbConnection;
                    command.Transaction = transaction as FbTransaction;
                }

                var keyScheme = Entities[entityName].EntityAttribute.KeyScheme;

                // TODO: fill the parameters
                foreach (var field in Entities[entityName].Fields)
                {
                    if ((field.IsPrimaryKey) && ((keyScheme == KeyScheme.Identity) || field.IsIdentity))
                    {
                        identity = field;
                        continue;
                    }
                    else if (isDynamicEntity)
                    {
                        object value = null;
                        if (entity.Fields[field.FieldName].DataType == DbType.Object)
                        {
                            if (entity.Serializer == null)
                            {
                                throw new MissingMethodException(
                                          string.Format("The field '{0}' requires a custom serializer/deserializer method pair in the '{1}' Entity",
                                                        field.FieldName, entity.EntityName));
                            }
                            value = entity.Serializer.Invoke(item, field.FieldName);
                        }
                        else
                        {
                            value = ((DynamicEntity)item)[field.FieldName];
                        }
                        if (value == null)
                        {
                            command.Parameters[String.Format("@{0}", field.FieldName)].Value = DBNull.Value;
                        }
                        else
                        {
                            command.Parameters[String.Format("@{0}", field.FieldName)].Value = value;
                        }
                    }
                    else
                    {
                        if (field.DataType == DbType.Object)
                        {
                            if (entity.Serializer == null)
                            {
                                throw new MissingMethodException(
                                          string.Format("The field '{0}' requires a custom serializer/deserializer method pair in the '{1}' Entity",
                                                        field.FieldName, entityName));
                            }
                            var value = entity.Serializer.Invoke(item, field.FieldName);
                            if (value == null)
                            {
                                command.Parameters[String.Format("@{0}", field.FieldName)].Value = DBNull.Value;
                            }
                            else
                            {
                                command.Parameters[String.Format("@{0}", field.FieldName)].Value = value;
                            }
                        }
                        else if (field.IsRowVersion)
                        {
                            // read-only, so do nothing
                        }
                        else if (field.PropertyInfo.PropertyType.UnderlyingTypeIs <TimeSpan>())
                        {
                            // SQL Compact doesn't support Time, so we're convert to a DateTime both directions
                            var value = field.PropertyInfo.GetValue(item, null);

                            if (value == null)
                            {
                                command.Parameters[String.Format("@{0}", field.FieldName)].Value = DBNull.Value;
                            }
                            else
                            {
                                var timespanTicks = ((TimeSpan)value).Ticks;
                                command.Parameters[String.Format("@{0}", field.FieldName)].Value = timespanTicks;
                            }
                        }
                        else
                        {
                            var value = field.PropertyInfo.GetValue(item, null);
                            if (value != null)
                            {
                                command.Parameters[String.Format("@{0}", field.FieldName)].Value = value;
                            }
                        }
                    }
                }

                command.ExecuteNonQuery();

                // did we have an identity field?  If so, we need to update that value in the item
                if (identity != null)
                {
                    int id = 0;
                    if (transaction == null)
                    {
                        id = GetIdentity(connection);
                    }
                    else
                    {
                        id = GetIdentity(transaction);
                    }
                    if (isDynamicEntity)
                    {
                        ((DynamicEntity)item)[identity.FieldName] = id;
                    }
                    else
                    {
                        identity.PropertyInfo.SetValue(item, id, null);
                    }
                }

                if (insertReferences)
                {
                    // cascade insert any References
                    // do this last because we need the PK from above
                    foreach (var reference in Entities[entityName].References)
                    {
                        var valueArray = reference.PropertyInfo.GetValue(item, null);
                        if (valueArray == null)
                        {
                            continue;
                        }

                        var fk = Entities[entityName].Fields.KeyField.PropertyInfo.GetValue(item, null);

                        string et = null;

                        if (reference.IsArray || reference.IsList)
                        {
                            foreach (var element in valueArray as System.Collections.IEnumerable)
                            {
                                if (et == null)
                                {
                                    et = m_entities.GetNameForType(element.GetType());
                                }
                                Entities[et].Fields[reference.ReferenceField].PropertyInfo.SetValue(element, fk, null);
                                if (checkUpdates)
                                {
                                    this.InsertOrUpdate(element, insertReferences, connection, transaction);
                                }
                                else
                                {
                                    this.Insert(element, insertReferences, connection, transaction, false);
                                }
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                }
            }
            finally
            {
                if (!bInheritedConnection)
                {
                    DoneWithConnection(connection, false);
                }
            }
        }
예제 #8
0
 internal void Add(FieldAttribute field)
 {
     Add(field.FieldName, null, null);
 }
예제 #9
0
        private void FillEntity(Action <int, object> setter, string entityName, Type itemType, object item, out FieldAttribute identity)
        {
            // The reason for this somewhat convoluted Action parameter is that while the SqlCeUpdateableRecord (from Insert)
            // and SqlCeResultSet (from Update) both contain a SetValue method, they don't share it on any common
            // interface.  using an Action allows us to share this code anyway.
            identity = null;

            var keyScheme = Entities[entityName].EntityAttribute.KeyScheme;

            foreach (var field in Entities[entityName].Fields)
            {
                if (field.IsPrimaryKey)
                {
                    switch (keyScheme)
                    {
                    case KeyScheme.Identity:
                        identity = field;
                        break;

                    case KeyScheme.GUID:
                        var value = GetInstanceValue(field, item);
                        if (value.Equals(Guid.Empty))
                        {
                            value = Guid.NewGuid();
                            SetInstanceValue(field, item, value);
                        }
                        setter(field.Ordinal, value);
                        break;
                    }
                }
                else if (field.DataType == DbType.Object)
                {
                    // get serializer
                    var serializer = GetSerializer(itemType);

                    if (serializer == null)
                    {
                        throw new MissingMethodException(
                                  string.Format("The field '{0}' requires a custom serializer/deserializer method pair in the '{1}' Entity",
                                                field.FieldName, entityName));
                    }
                    var value = serializer.Invoke(item, new object[] { field.FieldName });
                    if (value == null)
                    {
                        setter(field.Ordinal, DBNull.Value);
                    }
                    else
                    {
                        setter(field.Ordinal, value);
                    }
                }
                else if (field.DataType == DbType.DateTime)
                {
                    var dtValue = GetInstanceValue(field, item);

                    if (dtValue.Equals(DateTime.MinValue))
                    {
                        if ((!field.AllowsNulls) && (field.DefaultType != DefaultType.CurrentDateTime))
                        {
                            dtValue = SqlDateTime.MinValue;
                            setter(field.Ordinal, dtValue);
                        }
                        else
                        {
                            // let the null pass through
                        }
                    }
                    else
                    {
                        setter(field.Ordinal, dtValue);
                    }
                }
                else if (field.IsRowVersion)
                {
                    // read-only, so do nothing
                }
                else
                {
                    var iv = GetInstanceValue(field, item);

                    if ((iv == DBNull.Value) && (field.DefaultValue != null))
                    {
                        iv = field.DefaultValue;
                    }

                    setter(field.Ordinal, iv);
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Inserts the provided entity instance into the underlying data store.
        /// </summary>
        /// <param name="item"></param>
        /// <remarks>
        /// If the entity has an identity field, calling Insert will populate that field with the identity vale vefore returning
        /// </remarks>
        public override void OnInsert(object item, bool insertReferences)
        {
            string entityName;
            var    itemType = item.GetType();

            if (item is DynamicEntity)
            {
                entityName = (item as DynamicEntity).EntityName;
            }
            else
            {
                entityName = m_entities.GetNameForType(itemType);
            }

            var keyScheme = Entities[entityName].EntityAttribute.KeyScheme;

            if (entityName == null)
            {
                throw new EntityNotFoundException(item.GetType());
            }

            if (insertReferences)
            {
                DoInsertReferences(item, entityName, keyScheme, true);
            }

            // we'll use table direct for inserts - no point in getting the query parser involved in this
            var connection = GetConnection(false);

            try
            {
                CheckOrdinals(entityName);

                FieldAttribute identity = null;

                using (var command = new SqlCeCommand())
                {
                    command.Connection  = connection as SqlCeConnection;
                    command.Transaction = CurrentTransaction as SqlCeTransaction;
                    command.CommandText = entityName;
                    command.CommandType = CommandType.TableDirect;

                    using (var results = command.ExecuteResultSet(ResultSetOptions.Updatable))
                    {
                        var record = results.CreateRecord();

                        FillEntity(record.SetValue, entityName, itemType, item, out identity);

                        results.Insert(record);

                        // did we have an identity field?  If so, we need to update that value in the item
                        if (identity != null)
                        {
                            var id = GetIdentity(connection);
                            SetInstanceValue(identity, item, id);
                        }

                        if (insertReferences)
                        {
                            DoInsertReferences(item, entityName, keyScheme, false);
                        }
                    }

                    command.Dispose();
                }
            }
            finally
            {
                DoneWithConnection(connection, false);
            }
        }
예제 #11
0
        public override DynamicEntityDefinition DiscoverDynamicEntity(string entityName)
        {
            if (!TableExists(entityName))
            {
                throw new EntityNotFoundException(entityName);
            }

            var connection = GetConnection(true);

            try
            {
                using (var cmd = GetNewCommandObject())
                {
                    cmd.Connection  = connection;
                    cmd.Transaction = CurrentTransaction;

                    cmd.CommandText = string.Format(
                        "SELECT COLUMN_NAME, NULLABLE, DATA_TYPE, DATA_PRECISION, DATA_SCALE FROM all_tab_cols "
                        + " WHERE UPPER(TABLE_NAME) = UPPER('{0}') ORDER BY COLUMN_ID", entityName);

                    var fields = new List <FieldAttribute>();

                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var name     = reader.GetString(0);
                            var nullable = string.Compare(reader.GetString(1), "Y", true) == 0;
                            var type     = ParseDbType(reader.GetString(2));

                            var field = new FieldAttribute()
                            {
                                DataType    = type,
                                FieldName   = name,
                                AllowsNulls = nullable,
                            };

                            if (!reader.IsDBNull(3))
                            {
                                field.Precision = Convert.ToInt32(reader.GetValue(3));
                            }
                            if (!reader.IsDBNull(4))
                            {
                                field.Scale = Convert.ToInt32(reader.GetValue(4));
                            }

                            fields.Add(field);
                        }
                    }

                    //CONSTRAINT_TYPE (from 11gR2 docs)
                    //C - Check constraint on a table
                    //P - Primary key
                    //U - Unique key
                    //R - Referential integrity
                    //V - With check option, on a view
                    //O - With read only, on a view
                    //H - Hash expression
                    //F - Constraint that involves a REF column
                    //S - Supplemental logging

                    // INDEX_TYPE
                    // ASC == NORMAL
                    // DESC == FUNCTION-BASED NORMAL

                    cmd.CommandText = string.Format(
                        "SELECT cons.constraint_type, cons.constraint_name, cols.column_name, i.index_type " +
                        "FROM all_constraints cons " +
                        "LEFT OUTER JOIN all_cons_columns cols " +
                        "ON cons.table_name = cols.table_name " +
                        "LEFT OUTER JOIN all_indexes i " +
                        "ON cons.index_name = i.index_name " +
                        "WHERE UPPER(cols.table_name) = UPPER('{0}')"
                        , entityName);

                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var column = reader.GetString(2);
                            var ct     = reader.GetString(0).TrimEnd();
                            var pk     = false;
                            var unique = false;

                            switch (ct)
                            {
                            case "P":
                                pk     = true;
                                unique = true;
                                break;

                            case "U":
                                unique = true;
                                break;
                            }

                            var field = fields.FirstOrDefault(f => f.FieldName == column);
                            if (pk)
                            {
                                field.IsPrimaryKey = true;
                            }
                            else
                            {
                                var isdescending = reader.GetString(3).IndexOf("FUNTION-BASED", StringComparison.InvariantCultureIgnoreCase) >= 0;
                                field.SearchOrder = isdescending ? FieldSearchOrder.Descending : FieldSearchOrder.Ascending;
                            }
                            if (unique)
                            {
                                field.RequireUniqueValue = true;
                            }
                        }
                    }

                    var entityDefinition = new DynamicEntityDefinition(entityName, fields);
                    RegisterEntityInfo(entityDefinition);
                    return(entityDefinition);
                }
            }
            finally
            {
                DoneWithConnection(connection, true);
            }
        }
예제 #12
0
 public abstract bool FieldExists(EntityInfo entityInfo, FieldAttribute fieldInfo);
        /// <summary>
        /// Inserts the provided entity instance into the underlying data store.
        /// </summary>
        /// <param name="item"></param>
        /// <remarks>
        /// If the entity has an identity field, calling Insert will populate that field with the identity vale vefore returning
        /// </remarks>
        protected override void Insert(object item, bool insertReferences, IDbConnection connection, IDbTransaction transaction, bool checkUpdates)
        {
            var    isDynamicEntity = item is DynamicEntity;
            string entityName      = null;

            if (isDynamicEntity)
            {
                entityName = ((DynamicEntity)item).EntityName;
                if (!m_entities.HasEntity(entityName))
                {
                    throw new EntityNotFoundException(entityName);
                }
            }
            else
            {
                entityName = m_entities.GetNameForType(item.GetType());
            }

            if (entityName == null)
            {
                throw new EntityNotFoundException(item.GetType());
            }
            var entity = m_entities[entityName];

            Boolean bInheritedConnection = connection != null;

            if (transaction == null && connection == null)
            {
                connection = GetConnection(false);
            }
            try
            {
                OnBeforeInsert(item, insertReferences);
                var start = DateTime.Now;

                FieldAttribute identity = null;
                using (var command = new SqlCeCommand())
                {
                    if (transaction == null)
                    {
                        command.Connection = connection as SqlCeConnection;
                    }
                    else
                    {
                        command.Connection  = transaction.Connection as SqlCeConnection;
                        command.Transaction = transaction as SqlCeTransaction;
                    }
                    command.CommandText = entity.EntityName;
                    command.CommandType = CommandType.TableDirect;

                    using (var results = command.ExecuteResultSet(ResultSetOptions.Updatable))
                    {
                        var ordinals = GetOrdinals(entityName, results);

                        var record = results.CreateRecord();

                        var keyScheme = Entities[entity.EntityName].EntityAttribute.KeyScheme;

                        foreach (var field in Entities[entity.EntityName].Fields)
                        {
                            if ((keyScheme == KeyScheme.Identity) && field.IsPrimaryKey)
                            {
                                identity = field;
                            }
                            else if (isDynamicEntity)
                            {
                                object value = null;
                                if (entity.Fields[field.FieldName].DataType == DbType.Object)
                                {
                                    if (entity.Serializer == null)
                                    {
                                        throw new MissingMethodException(
                                                  string.Format("The field '{0}' requires a custom serializer/deserializer method pair in the '{1}' Entity",
                                                                field.FieldName, entity.EntityName));
                                    }
                                    value = entity.Serializer.Invoke(item, field.FieldName);
                                }
                                else
                                {
                                    value = ((DynamicEntity)item)[field.FieldName];
                                }
                                if (value == null)
                                {
                                    record.SetValue(ordinals[field.FieldName], DBNull.Value);
                                }
                                else
                                {
                                    record.SetValue(ordinals[field.FieldName], value);
                                }
                            }
                            else
                            {
                                if (field.DataType == DbType.Object)
                                {
                                    if (entity.Serializer == null)
                                    {
                                        throw new MissingMethodException(
                                                  string.Format("The field '{0}' requires a custom serializer/deserializer method pair in the '{1}' Entity",
                                                                field.FieldName, entity.EntityName));
                                    }
                                    var value = entity.Serializer.Invoke(item, field.FieldName);
                                    if (value == null)
                                    {
                                        record.SetValue(ordinals[field.FieldName], DBNull.Value);
                                    }
                                    else
                                    {
                                        record.SetValue(ordinals[field.FieldName], value);
                                    }
                                }
                                else if (field.IsRowVersion)
                                {
                                    // read-only, so do nothing
                                }
                                else if (field.PropertyInfo.PropertyType.UnderlyingTypeIs <TimeSpan>())
                                {
                                    // SQL Compact doesn't support Time, so we're convert to a DateTime both directions
                                    var value = field.PropertyInfo.GetValue(item, null);

                                    if (value == null)
                                    {
                                        record.SetValue(ordinals[field.FieldName], DBNull.Value);
                                    }
                                    else
                                    {
                                        var timespanTicks = ((TimeSpan)value).Ticks;
                                        record.SetValue(ordinals[field.FieldName], timespanTicks);
                                    }
                                }
                                else
                                {
                                    var value = field.PropertyInfo.GetValue(item, null);
                                    record.SetValue(ordinals[field.FieldName], value);
                                }
                            }
                        }

                        results.Insert(record);

                        // did we have an identity field?  If so, we need to update that value in the item
                        if (identity != null)
                        {
                            int id = 0;
                            if (transaction == null)
                            {
                                id = GetIdentity(connection);
                            }
                            else
                            {
                                id = GetIdentity(transaction);
                            }
                            if (isDynamicEntity)
                            {
                                ((DynamicEntity)item)[identity.FieldName] = id;
                            }
                            else
                            {
                                identity.PropertyInfo.SetValue(item, id, null);
                            }
                        }

                        if (insertReferences)
                        {
                            // cascade insert any References
                            // do this last because we need the PK from above
                            foreach (var reference in Entities[entity.EntityName].References)
                            {
                                var valueArray = reference.PropertyInfo.GetValue(item, null);
                                if (valueArray == null)
                                {
                                    continue;
                                }

                                // Modified - 2012.08.16 - Corrected an error where the bad keyfield was used.
                                //var fk = Entities[entityName].Fields[reference.ReferenceField].PropertyInfo.GetValue(item, null);
                                var fk = Entities[entity.EntityName].Fields.KeyField.PropertyInfo.GetValue(item, null);

                                string et = null;

                                if (reference.IsArray || reference.IsList)
                                {
                                    foreach (var element in valueArray as System.Collections.IEnumerable)
                                    {
                                        if (et == null)
                                        {
                                            et = m_entities.GetNameForType(element.GetType());
                                        }

                                        // Added - 2012.08.08 - Replacing the old code to handle existing objects which were added
                                        Entities[et].Fields[reference.ReferenceField].PropertyInfo.SetValue(element, fk, null);
                                        if (checkUpdates)
                                        {
                                            this.InsertOrUpdate(element, insertReferences, connection, transaction);
                                        }
                                        else
                                        {
                                            this.Insert(element, insertReferences, connection, transaction, checkUpdates);
                                        }
                                    }
                                }
                                else
                                {
                                    throw new NotImplementedException();
                                }
                            }
                        }
                    }
                }
                OnAfterInsert(item, insertReferences, DateTime.Now.Subtract(start), null);
            }
            finally
            {
                if (!bInheritedConnection)
                {
                    DoneWithConnection(connection, false);
                }
            }
        }
예제 #14
0
 protected void AddField(FieldAttribute field)
 {
     Fields.Add(field);
 }
예제 #15
0
        protected override string GetFieldCreationAttributes(EntityAttribute attribute, FieldAttribute field)
        {
            switch (field.DataType)
            {
            case DbType.Guid:
                return("(16)");    // guids are "RAW(16)"

            default:
                return(base.GetFieldCreationAttributes(attribute, field));
            }
        }
예제 #16
0
        public override void OnInsert(object item, bool insertReferences)
        {
            if (item is DynamicEntity)
            {
                OnInsertDynamicEntity(item as DynamicEntity, insertReferences);
                return;
            }

            string entityName;
            var    itemType = item.GetType();

            entityName = m_entities.GetNameForType(itemType);

            if (entityName == null)
            {
                throw new EntityNotFoundException(item.GetType());
            }

            var keyScheme = Entities[entityName].EntityAttribute.KeyScheme;

            // ---------- Handle N:1 References -------------
            if (insertReferences)
            {
                DoInsertReferences(item, entityName, keyScheme, true);
            }

            var connection = GetConnection(false);

            try
            {
                FieldAttribute identity = null;
                keyScheme = Entities[entityName].EntityAttribute.KeyScheme;
                var command = GetInsertCommand(entityName);
                command.Connection  = connection  as OracleConnection;
                command.Transaction = CurrentTransaction as OracleTransaction;

                // TODO: fill the parameters
                foreach (var field in Entities[entityName].Fields)
                {
                    if ((field.IsPrimaryKey) && (keyScheme == KeyScheme.Identity))
                    {
                        identity = field;
                        continue;
                    }
                    else if (field.DataType == DbType.Object)
                    {
                        // get serializer
                        var serializer = GetSerializer(itemType);

                        if (serializer == null)
                        {
                            throw new MissingMethodException(
                                      string.Format("The field '{0}' requires a custom serializer/deserializer method pair in the '{1}' Entity",
                                                    field.FieldName, entityName));
                        }
                        var value = serializer.Invoke(item, new object[] { field.FieldName });
                        if (value == null)
                        {
                            command.Parameters[field.FieldName].Value = DBNull.Value;
                        }
                        else
                        {
                            command.Parameters[field.FieldName].Value = value;
                        }
                    }
                    else if (field.DataType == DbType.DateTime)
                    {
                        var dtValue = GetInstanceValue(field, item);

                        if (dtValue.Equals(DateTime.MinValue) &&
                            ((field.AllowsNulls) || (field.DefaultType == DefaultType.CurrentDateTime)))
                        {
                            // testing of just letting the null fall through is setting the field to null, not using the default
                            // so we'll set it manually
                            dtValue = DateTime.Now;
                        }
                        command.Parameters[field.FieldName].Value = dtValue;
                    }
                    else if (field.DataType == DbType.Guid)
                    {
                        // read-only, so do nothing
                        var guid = field.PropertyInfo.GetValue(item, null);
                        if (guid == null)
                        {
                            command.Parameters[field.FieldName].Value = DBNull.Value;
                        }
                        else
                        {
                            command.Parameters[field.FieldName].Value = ((Guid)guid).ToByteArray();
                        }
                    }
                    else if (field.PropertyInfo.PropertyType.UnderlyingTypeIs <TimeSpan>())
                    {
                        // SQL Compact doesn't support Time, so we're convert to a DateTime both directions
                        var value = field.PropertyInfo.GetValue(item, null);

                        if (value == null)
                        {
                            command.Parameters[field.FieldName].Value = DBNull.Value;
                        }
                        else
                        {
                            var timespanTicks = ((TimeSpan)value).Ticks;
                            command.Parameters[field.FieldName].Value = timespanTicks;
                        }
                    }
                    else
                    {
                        var value = field.PropertyInfo.GetValue(item, null);
                        if (value == null)
                        {
                            if (field.DefaultValue != null)
                            {
                                command.Parameters[field.FieldName].Value = field.DefaultValue;
                            }
                            else
                            {
                                command.Parameters[field.FieldName].Value = DBNull.Value;
                            }
                        }
                        else
                        {
                            command.Parameters[field.FieldName].Value = value;
                        }
                    }
                }

                // did we have an identity field?  If so, we need to update that value in the item
                if (identity == null)
                {
                    command.ExecuteNonQuery();
                }
                else
                {
                    var idParameter = new OracleParameter(":LASTID", OracleDbType.Int32);
                    idParameter.Direction = ParameterDirection.Output;
                    command.Parameters.Add(idParameter);

                    command.ExecuteNonQuery();

                    identity.PropertyInfo.SetValue(item, idParameter.Value, null);
                }

                if (insertReferences)
                {
                    // ---------- Handle 1:N References -------------
                    DoInsertReferences(item, entityName, keyScheme, false);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }
                throw;
            }
            finally
            {
                DoneWithConnection(connection, false);
            }
        }
예제 #17
0
        public override DynamicEntityDefinition DiscoverDynamicEntity(string entityName)
        {
            if (!TableExists(entityName))
            {
                return(null);
            }

            var connection = GetConnection(true);

            try
            {
                using (var cmd = GetNewCommandObject())
                {
                    cmd.Connection  = connection;
                    cmd.Transaction = CurrentTransaction;

                    cmd.CommandText = string.Format("SELECT COLUMN_NAME, ORDINAL_POSITION, IS_NULLABLE, DATA_TYPE, NUMERIC_PRECISION, NUMERIC_SCALE FROM information_schema.columns WHERE TABLE_NAME = '{0}' ORDER BY ORDINAL_POSITION", entityName);

                    var fields = new List <FieldAttribute>();

                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var name     = reader.GetString(0);
                            var nullable = string.Compare(reader.GetString(2), "YES", true) == 0;
                            var type     = reader.GetString(3).ParseToDbType();

                            var field = new FieldAttribute()
                            {
                                DataType    = type,
                                FieldName   = name,
                                AllowsNulls = nullable,
                            };

                            if (!reader.IsDBNull(4))
                            {
                                field.Precision = Convert.ToInt32(reader.GetValue(4));
                            }
                            if (!reader.IsDBNull(5))
                            {
                                field.Scale = Convert.ToInt32(reader.GetValue(5));
                            }

                            fields.Add(field);
                        }
                    }

                    cmd.CommandText = string.Format("SELECT COLUMN_NAME, PRIMARY_KEY, [UNIQUE], COLLATION FROM information_schema.indexes WHERE TABLE_NAME = '{0}'", entityName);

                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var column = reader.GetString(0);
                            var pk     = Convert.ToBoolean(reader.GetValue(1));
                            var unique = Convert.ToBoolean(reader.GetValue(2));

                            var field = fields.FirstOrDefault(f => f.FieldName == column);
                            if (pk)
                            {
                                field.IsPrimaryKey = true;
                            }
                            else
                            {
                                var collation = Convert.ToInt32(reader.GetValue(3));
                                field.SearchOrder = collation == 1 ? FieldSearchOrder.Ascending : FieldSearchOrder.Descending;
                            }
                            if (unique)
                            {
                                field.RequireUniqueValue = true;
                            }
                        }
                    }


                    var entityDefinition = new DynamicEntityDefinition(entityName, fields);
                    RegisterEntityInfo(entityDefinition);
                    return(entityDefinition);
                }
            }
            finally
            {
                DoneWithConnection(connection, true);
            }
        }
예제 #18
0
        public EntityInfo[] GetEntityDefinitions()
        {
            ValidateConnection();

            var entities = new List<EntityInfo>();

            using (var connection = new SqlCeConnection(m_connectionString))
            using (var cmd = new SqlCeCommand(GetTablesSQL, connection))
            {
                connection.Open();
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var info = new EntityInfo();
                        var indexInfo = new Dictionary<string, IndexInfo>();

                        info.Entity = new EntityAttribute();
                        info.Entity.NameInStore = reader.GetString(0);

                        using(var indexCommand = new SqlCeCommand(
                            string.Format("SELECT INDEX_NAME, PRIMARY_KEY, COLUMN_NAME, COLLATION FROM INFORMATION_SCHEMA.INDEXES WHERE TABLE_NAME = '{0}'", info.Entity.NameInStore),
                            connection))
                        using (var indexReader = indexCommand.ExecuteReader())
                        {
                            while(indexReader.Read())
                            {
                                var indexName = indexReader.GetString(0);
                                var primaryKey = indexReader.GetBoolean(1);
                                var columnName = indexReader.GetString(2);
                                var sortOrder = indexReader.GetInt16(3) == 1 ? FieldOrder.Ascending : FieldOrder.Descending;
                                // collation of 1 == ascending, 2 == descending (based on a quick test, this might be incorrect)

                                // TODO: handle cases where a column is in multiple indexes (ORM doesn't support that scenario for now)
                                if (!indexInfo.ContainsKey(columnName))
                                {
                                    indexInfo.Add(columnName, new IndexInfo()
                                    {
                                        ColumnName = columnName,
                                        IndexName = indexName,
                                        PrimaryKey = primaryKey,
                                        SearchOrder = sortOrder
                                    });
                                }
                            }
                        }

                        // TODO: look for primary key to set key scheme
                        info.Entity.KeyScheme = KeyScheme.None;

                        using (var fieldCommand = new SqlCeCommand(
                            string.Format("SELECT COLUMN_NAME, COLUMN_HASDEFAULT, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE, AUTOINC_SEED FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{0}'", info.Entity.NameInStore),
                            connection))
                        {
                            using (var fieldReader = fieldCommand.ExecuteReader())
                            {
                                while (fieldReader.Read())
                                {
                                    var field = new FieldAttribute();
                                    field.FieldName = fieldReader.GetString(0);
                                    field.AllowsNulls = string.Compare(fieldReader.GetString(2), "YES", true) == 0;
                                    field.DataType = fieldReader.GetString(3).ParseToDbType();
                                    object val = fieldReader[4];
                                    if(!val.Equals(DBNull.Value))
                                    {
                                        field.Length = Convert.ToInt32(val);
                                    }
                                    val = fieldReader[5];
                                    if (!val.Equals(DBNull.Value))
                                    {
                                        field.Precision = Convert.ToInt32(val);
                                    }
                                    val = fieldReader[6];
                                    if (!val.Equals(DBNull.Value))
                                    {
                                        field.Scale = Convert.ToInt32(val);
                                    }
                                    val = fieldReader[7];
                                    if (!val.Equals(DBNull.Value))
                                    {
                                        // identity field, so it must be the PK (or part of it)
                                        info.Entity.KeyScheme = KeyScheme.Identity;
                                    }

                                    // check for indexes
                                    if (indexInfo.ContainsKey(field.FieldName))
                                    {
                                        var idx = indexInfo[field.FieldName];

                                        if (idx.PrimaryKey)
                                        {
                                            field.IsPrimaryKey = true;

                                            if (field.DataType == DbType.Guid)
                                            {
                                                info.Entity.KeyScheme = KeyScheme.GUID;
                                            }
                                        }
                                        field.SearchOrder = idx.SearchOrder;
                                    }

                                    // TODO: populate the remainder of the field info
                                    info.Fields.Add(field);
                                }
                            }
                        }
                        entities.Add(info);
                    }
                }
            }

            return entities.ToArray();
        }
예제 #19
0
        public static Field GetFieldForAttribute(FieldAttribute attrib, KeyScheme keyScheme)
        {
            Field field = null;

            switch (attrib.DataType)
            {
            case System.Data.DbType.Int32:
                field = new Field <int>(attrib.FieldName);
                if (attrib.IsPrimaryKey)
                {
                    if (keyScheme == KeyScheme.Identity)
                    {
                        // As of 10/28/2013, if a field is a PK, DreamFactory forces it to be an auto-incrementing number
                        field.IsPrimaryKey  = true;
                        field.AutoIncrement = true;
                    }
                }
                break;

            case System.Data.DbType.Int64:
                field = new Field <long>(attrib.FieldName);
                break;

            case System.Data.DbType.Byte:
                field = new Field <byte>(attrib.FieldName);
                break;

            case System.Data.DbType.Int16:
                field = new Field <short>(attrib.FieldName);
                break;

            case System.Data.DbType.String:
            case System.Data.DbType.StringFixedLength:
                field = new Field <string>(attrib.FieldName);
                if (attrib.Length <= 0)
                {
                    field.Length = DefaultStringLength;
                }
                else if (attrib.Length > MaxStringLength)
                {
                    field.Length = MaxStringLength;
                }
                else
                {
                    field.Length = attrib.Length;
                }

                break;

            case System.Data.DbType.Boolean:
                field = new Field <bool>(attrib.FieldName);
                break;

            case System.Data.DbType.Single:
                field           = new Field <float>(attrib.FieldName);
                field.Scale     = attrib.Scale <= 0 ? DefaultDoubleScale : attrib.Scale;
                field.Precision = attrib.Precision <= 0 ? DefaultDoublePrecision : attrib.Precision;
                break;

            case System.Data.DbType.Double:
                field           = new Field <double>(attrib.FieldName);
                field.Scale     = attrib.Scale <= 0 ? DefaultDoubleScale : attrib.Scale;
                field.Precision = attrib.Precision <= 0 ? DefaultDoublePrecision : attrib.Precision;
                break;

            case System.Data.DbType.Decimal:
                field = new Field <decimal>(attrib.FieldName);
//                    field.Scale = attrib.Scale;
//                    field.Precision = attrib.Precision;
                break;

            case System.Data.DbType.DateTime:
                field = new Field <DateTime>(attrib.FieldName);
                break;

            case System.Data.DbType.Time:
                field = new Field <TimeSpan>(attrib.FieldName);
                break;

            case System.Data.DbType.Guid:
            case System.Data.DbType.Binary:
                field = new Field <byte[]>(attrib.FieldName);
                break;

            default:
                if (Debugger.IsAttached)
                {
                    Debugger.Break();
                }
                throw new NotSupportedException(string.Format("Field type '{0}' is not supported.", attrib.DataType.ToString()));
            }

            field.AllowsNull = attrib.AllowsNulls;

            return(field);
        }
예제 #20
0
        protected override Boolean FieldExists(IDbConnection connection, EntityInfo entity, FieldAttribute field)
        {
            Boolean exists = false;

            try
            {
                // ANSI SQL way.  Works in PostgreSQL, MSSQL, MySQL.
                using (var command = GetNewCommandObject())
                {
                    command.CommandText = String.Format("select count(*) from Information_SCHEMA.columns where table_name='{0}' and column_name='{1}'", entity.EntityName, field.FieldName);
                    command.Connection  = connection;
                    exists = (int)command.ExecuteScalar() > 0;
                }
            }
            catch
            {
                try
                {
                    exists = true;
                    //TODO: Bad practice, but works across all DBs, need to work on a better test
                    using (var command = GetNewCommandObject())
                    {
                        command.CommandText = String.Format("select {1} from {0} where 1 = 0", entity.EntityName, field.FieldName);
                        command.Connection  = connection;
                        command.ExecuteNonQuery();
                    }
                }
                catch
                {
                    exists = false;
                }
            }
            return(exists);
        }
예제 #21
0
        /// <summary>
        /// Inserts the provided entity instance into the underlying data store.
        /// </summary>
        /// <param name="item"></param>
        /// <remarks>
        /// If the entity has an identity field, calling Insert will populate that field with the identity vale vefore returning
        /// </remarks>
        public override void OnInsert(object item, bool insertReferences)
        {
            if (item is DynamicEntity)
            {
                OnInsertDynamicEntity(item as DynamicEntity, insertReferences);
                return;
            }

            var    itemType   = item.GetType();
            string entityName = m_entities.GetNameForType(itemType);
            var    keyScheme  = Entities[entityName].EntityAttribute.KeyScheme;

            if (entityName == null)
            {
                throw new EntityNotFoundException(item.GetType());
            }

            // ---------- Handle N:1 References -------------
            if (insertReferences)
            {
                DoInsertReferences(item, entityName, keyScheme, true);
            }

            var connection = GetConnection(false);

            try
            {
                FieldAttribute identity = null;
                var            command  = GetInsertCommand(entityName);
                command.Connection  = connection as SQLiteConnection;
                command.Transaction = CurrentTransaction as SQLiteTransaction;

                // TODO: fill the parameters
                foreach (var field in Entities[entityName].Fields)
                {
                    if ((field.IsPrimaryKey) && (keyScheme == KeyScheme.Identity))
                    {
                        identity = field;
                        continue;
                    }
                    else if (field.DataType == DbType.Object)
                    {
                        // get serializer
                        var serializer = GetSerializer(itemType);

                        if (serializer == null)
                        {
                            throw new MissingMethodException(
                                      string.Format("The field '{0}' requires a custom serializer/deserializer method pair in the '{1}' Entity",
                                                    field.FieldName, entityName));
                        }
                        var value = serializer.Invoke(item, new object[] { field.FieldName });
                        if (value == null)
                        {
                            command.Parameters[ParameterPrefix + field.FieldName].Value = DBNull.Value;
                        }
                        else
                        {
                            command.Parameters[ParameterPrefix + field.FieldName].Value = value;
                        }
                    }
                    else if (field.DataType == DbType.DateTime)
                    {
                        var dtValue = GetInstanceValue(field, item);

                        if (dtValue.Equals(DateTime.MinValue) &&
                            ((field.AllowsNulls) || (field.DefaultType == DefaultType.CurrentDateTime)))
                        {
                            // testing of just letting the null fall through is setting the field to null, not using the default
                            // so we'll set it manually
                            dtValue = DateTime.Now;
                        }
                        command.Parameters[ParameterPrefix + field.FieldName].Value = dtValue;
                    }
                    else if (field.IsRowVersion)
                    {
                        // read-only, so do nothing
                    }
                    else if (field.PropertyInfo.PropertyType.UnderlyingTypeIs <TimeSpan>())
                    {
                        // SQLite doesn't support "timespan" - and date/time must be stored as text, real or 64-bit integer (see the SQLite docs for more details)
                        // here we'll store TimeSpans (since they can be negative) as an offset from a base date
                        var value = field.PropertyInfo.GetValue(item, null);

                        if (value == null)
                        {
                            command.Parameters[ParameterPrefix + field.FieldName].Value = DBNull.Value;
                        }
                        else
                        {
                            var storeTime = new DateTime(1980, 1, 1) + (TimeSpan)value;
                            command.Parameters[ParameterPrefix + field.FieldName].Value = storeTime;
                        }
                    }
                    else
                    {
                        var value = field.PropertyInfo.GetValue(item, null);
                        if ((value == null) && (field.DefaultValue != null))
                        {
                            command.Parameters[ParameterPrefix + field.FieldName].Value = field.DefaultValue;
                        }
                        else
                        {
                            command.Parameters[ParameterPrefix + field.FieldName].Value = value;
                        }
                    }
                }

                command.ExecuteNonQuery();

                // did we have an identity field?  If so, we need to update that value in the item
                if (identity != null)
                {
                    var id = GetIdentity(connection);
                    identity.PropertyInfo.SetValue(item, id, null);
                }

                if (insertReferences)
                {
                    // ---------- Handle 1:N References -------------
                    DoInsertReferences(item, entityName, keyScheme, false);
                }
            }
            finally
            {
                DoneWithConnection(connection, false);
            }
        }
예제 #22
0
        public override DynamicEntityDefinition DiscoverDynamicEntity(string entityName)
        {
            if (!TableExists(entityName))
            {
                return(null);
            }

            var connection = GetConnection(true);

            try
            {
                using (var cmd = GetNewCommandObject())
                {
                    cmd.Connection  = connection;
                    cmd.Transaction = CurrentTransaction;

                    cmd.CommandText = string.Format("PRAGMA table_info({0})", entityName);

                    // cid, name, type, notnull, dflt_value, pk
                    var fields = new List <FieldAttribute>();

                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var cid      = reader.GetInt64(0);
                            var name     = reader.GetString(1);
                            var type     = reader.GetString(2).ParseToDbType();
                            var nullable = reader.GetInt64(3) == 0;
                            // 4 == default value - TODO
                            var isPK = reader.GetInt64(5) == 1;

                            var field = new FieldAttribute()
                            {
                                DataType     = type,
                                FieldName    = name,
                                AllowsNulls  = nullable,
                                IsPrimaryKey = isPK
                            };

                            fields.Add(field);
                        }
                    }

                    cmd.CommandText = string.Format("SELECT 1 FROM sqlite_master WHERE tbl_name='{0}' AND sql LIKE '%AUTOINCREMENT%'", entityName);

                    var autoIncrement = cmd.ExecuteScalar();

                    // TODO: handle index metadata (ascending/descending, unique, etc)
                    // PRAGMA index_list(TABLENAME)
                    // seq | name | unique
                    // PRAGMA index_info(INDEXNAME)
                    // seqno | cid | name |


                    var entityDefinition = new DynamicEntityDefinition(entityName, fields);

                    try
                    {
                        if (Convert.ToInt64(autoIncrement) == 1L)
                        {
                            entityDefinition.EntityAttribute.KeyScheme = KeyScheme.Identity;
                        }
                    }
                    catch
                    {
                        // not auto-increment
                    }

                    RegisterEntityInfo(entityDefinition);

                    return(entityDefinition);
                }
            }
            finally
            {
                DoneWithConnection(connection, true);
            }
        }
예제 #23
0
 public void AddField(FieldAttribute field)
 {
     Fields.Add(field);
 }
예제 #24
0
        public override DynamicEntityDefinition DiscoverDynamicEntity(string entityName)
        {
            if (!TableExists(entityName))
            {
                return(null);
            }

            var connection = GetConnection(true);

            try
            {
                using (var cmd = GetNewCommandObject())
                {
                    cmd.Connection  = connection;
                    cmd.Transaction = CurrentTransaction;

                    cmd.CommandText = string.Format("SELECT COLUMN_NAME, ORDINAL_POSITION, IS_NULLABLE, DATA_TYPE, NUMERIC_PRECISION, NUMERIC_SCALE, CHARACTER_MAXIMUM_LENGTH "
                                                    + "FROM information_schema.columns WHERE TABLE_NAME = '{0}' ORDER BY ORDINAL_POSITION", entityName);

                    var fields = new List <FieldAttribute>();

                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var name     = reader.GetString(0);
                            var nullable = string.Compare(reader.GetString(2), "YES", true) == 0;
                            var type     = reader.GetString(3).ParseToDbType();

                            var field = new FieldAttribute()
                            {
                                DataType    = type,
                                FieldName   = name,
                                AllowsNulls = nullable,
                            };

                            if (!reader.IsDBNull(4))
                            {
                                field.Precision = Convert.ToInt32(reader.GetValue(4));
                            }
                            if (!reader.IsDBNull(5))
                            {
                                field.Scale = Convert.ToInt32(reader.GetValue(5));
                            }

                            if (!reader.IsDBNull(6))
                            {
                                field.Length = Convert.ToInt32(reader.GetValue(6));
                            }

                            fields.Add(field);
                        }
                    }

                    cmd.CommandText = string.Format(
                        "SELECT ac.name, ind.is_primary_key, ind.is_unique, ic.is_descending_key, col.collation_name, idc.name " +
                        "FROM sys.indexes ind " +
                        "INNER JOIN sys.index_columns ic " +
                        "  ON  ind.object_id = ic.object_id and ind.index_id = ic.index_id " +
                        "INNER JOIN sys.columns col  " +
                        "  ON ic.object_id = col.object_id and ic.column_id = col.column_id  " +
                        "INNER JOIN sys.tables t  " +
                        "  ON ind.object_id = t.object_id " +
                        "INNER JOIN sys.identity_columns idc " +
                        "  ON col.object_id = idc.object_id and col.column_id = idc.column_id " +
                        "INNER JOIN sys.columns ac " +
                        "  ON ac.object_id = col.object_id and ac.column_id = col.column_id " +
                        "WHERE t.name = '{0}'", entityName);

                    string identiyColumn = null;

                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var column = reader.GetString(0);
                            var pk     = Convert.ToBoolean(reader.GetValue(1));
                            var unique = Convert.ToBoolean(reader.GetValue(2));

                            var field = fields.FirstOrDefault(f => f.FieldName == column);
                            if (pk)
                            {
                                field.IsPrimaryKey = true;
                            }
                            else
                            {
                                var isdescending = Convert.ToInt32(reader.GetValue(3));
                                field.SearchOrder = isdescending == 0 ? FieldSearchOrder.Ascending : FieldSearchOrder.Descending;
                            }
                            if (unique)
                            {
                                field.RequireUniqueValue = true;
                            }

                            identiyColumn = reader.GetString(5);
                        }
                    }


                    var entityDefinition = new DynamicEntityDefinition(
                        entityName,
                        fields,
                        string.IsNullOrEmpty(identiyColumn) ? KeyScheme.None : KeyScheme.Identity);

                    RegisterEntityInfo(entityDefinition);

                    return(entityDefinition);
                }
            }
            finally
            {
                DoneWithConnection(connection, true);
            }
        }
예제 #25
0
        private Dictionary <string, object> GetEntityValueDictionary(object item, out FieldAttribute identityField)
        {
            var entityName = GetEntityNameForInstance(item);

            var values = new Dictionary <string, object>();

            identityField = null;

            if (item is DynamicEntity)
            {
                var de = item as DynamicEntity;

                foreach (var field in Entities[entityName].Fields)
                {
                    if ((field.IsPrimaryKey) && (Entities[entityName].EntityAttribute.KeyScheme == KeyScheme.Identity))
                    {
                        identityField = field;
                    }

                    var value = de.Fields[field.FieldName];

                    if ((field.AllowsNulls) && (value == null))
                    {
                        values.Add(field.FieldName, null);
                    }
                    else
                    {
                        switch (field.DataType)
                        {
                        case System.Data.DbType.Time:
                            values.Add(field.FieldName, ((TimeSpan)value).ToString());
                            break;

                        case System.Data.DbType.Date:
                        case System.Data.DbType.DateTime:
                        case System.Data.DbType.DateTime2:
                            values.Add(field.FieldName, Convert.ToDateTime(value).ToString("s"));
                            break;

                        default:
                            values.Add(field.FieldName, value);
                            break;
                        }
                    }
                }
            }
            else
            {
                foreach (var field in Entities[entityName].Fields)
                {
                    if (field.IsPrimaryKey)
                    {
                        identityField = field;
                    }

                    var value = field.PropertyInfo.GetValue(item, null);

                    if ((field.AllowsNulls) && (value == null))
                    {
                        values.Add(field.FieldName, null);
                    }
                    else
                    {
                        switch (field.DataType)
                        {
                        case System.Data.DbType.Time:
                            values.Add(field.FieldName, ((TimeSpan)value).ToString());
                            break;

                        case System.Data.DbType.Date:
                        case System.Data.DbType.DateTime:
                        case System.Data.DbType.DateTime2:
                            values.Add(field.FieldName, Convert.ToDateTime(value).ToString("s"));
                            break;

                        default:
                            values.Add(field.FieldName, value);
                            break;
                        }
                    }
                }
            }
            return(values);
        }
예제 #26
0
        protected override Boolean FieldExists(IDbConnection connection, EntityInfo entity, FieldAttribute field)
        {
            Boolean exists = false;

            try
            {
                using (var command = GetNewCommandObject())
                {
                    command.CommandText = String.Format("PRAGMA table_info('{0}')", entity.EntityName, field.FieldName);
                    OnSqlStatementCreated(command, null);
                    command.Connection = connection;
                    using (var results = command.ExecuteReader())
                    {
                        while (results.Read())
                        {
                            if (results["name"].ToString().Equals(field.FieldName))
                            {
                                exists = true;
                                break;
                            }
                        }
                    }
                }
            }
            catch
            {
                try
                {
                    exists = true;
                    //TODO: Bad practice, but works across all DBs, need to work on a better test
                    using (var command = GetNewCommandObject())
                    {
                        command.CommandText = String.Format("select {1} from {0} where 1 = 0", entity.EntityName, field.FieldName);
                        command.Connection  = connection;
                        command.ExecuteNonQuery();
                    }
                }
                catch
                {
                    exists = false;
                }
            }
            return(exists);
        }
예제 #27
0
        private CodeAttributeArgument[] GenerateFieldArguments(FieldAttribute field)
        {
            var attrList = new List<CodeAttributeArgument>();

            // TODO add precision, etc.

            if (field.IsPrimaryKey)
            {
                attrList.Add(new CodeAttributeArgument(new CodeSnippetExpression("IsPrimaryKey=true")));
            }

            if (field.SearchOrder != FieldOrder.None)
            {
                attrList.Add(new CodeAttributeArgument(new CodeSnippetExpression("SearchOrder=FieldSearchOrder." + field.SearchOrder.ToString())));
            }

            return attrList.ToArray();
        }