Пример #1
0
        private static void ProcessManagedProperties(Type type, DbTable table, EntityMeta em)
        {
            foreach (var property in em.EntityProperties)
            {
                var meta = property.ColumnMeta;
                if (meta == null)
                {
                    continue;
                }

                var propertyName = property.Name;

                //生成 ManagedPropertyBridge
                var epm = em.Property(propertyName);
                if (epm == null)
                {
                    throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", type.FullName, propertyName));
                }
                var mp = epm.ManagedProperty as IProperty;

                //列名
                var columnName = meta.ColumnName;
                if (string.IsNullOrWhiteSpace(columnName))
                {
                    columnName = propertyName;
                }

                var column = table.CreateColumn(columnName, epm);
                column.IsIdentity   = meta.IsIdentity;
                column.IsPrimaryKey = meta.IsPrimaryKey;
                table.Add(column);
            }
        }
Пример #2
0
        private static void ProcessManagedProperties(Type type, PersistanceTableInfo table, EntityMeta em)
        {
            foreach (var property in em.EntityProperties)
            {
                var meta = property.ColumnMeta;
                if (meta == null)
                {
                    continue;
                }

                var propertyName = property.Name;

                //生成 ManagedPropertyBridge
                var epm = em.Property(propertyName);
                if (epm == null)
                {
                    throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", type.FullName, propertyName));
                }


                var column = new PersistanceColumnInfo(epm, meta, table);

                if (meta.IsPrimaryKey)
                {
                    table.PKColumn = column;
                }

                table.Columns.Add(column);
            }
        }
Пример #3
0
        /// <summary>
        /// 禁用实体的幽灵(假删除)功能。
        /// </summary>
        /// <param name="meta"></param>
        public static void DisablePhantoms(this EntityMeta meta)
        {
            meta.IsPhantomEnabled = false;

            meta.Property(EntityPhantomExtension.IsPhantomProperty).DontMapColumn();

            meta.DeletingChildrenInMemory = false;
        }
Пример #4
0
        private void TrySetProperty(Entity e, string pName, JToken value)
        {
            //有些小写的客户端数据被传输到了服务端,需要被过滤掉。
            if (char.IsLower(pName[0]))
            {
                return;
            }

            var pm = _entityMeta.Property(pName) as PropertyMeta ??
                     _entityMeta.ChildrenProperty(pName);

            if (pm != null)
            {
                var mp = pm.ManagedProperty;
                if (mp is IListProperty)
                {
                    //todo: 此处的性能可能需要优化,聚合保存子列表时,重复的查询 Repository
                    var entityType = EntityMatrix.FindByList(pm.PropertyType).EntityType;
                    var repo       = RF.Find(entityType);

                    //列表属性的设置不能使用 SetProperty,否则,list.Parent 将会无值。
                    //但是也不能直接使用 LoadProperty,否则会导致调用 list.MarkOld,从而不会保存这个列表。
                    //所以只能先装载一个空列表,然后再把 json 中的数据转换为实体加入到这个列表中。
                    var list = repo.NewList();
                    e.LoadProperty(mp, list);

                    ListReader.JsonToEntity(value as JObject, repo, list);
                }
                else
                {
                    var rawValue = (value as JValue).Value;

                    rawValue = EntityJsonConverter.ToServerValue(pm.PropertyType, rawValue);

                    e.SetProperty(mp, rawValue, ManagedPropertyChangedSource.FromUIOperating);
                }
            }
            else
            {
                var rawValue = (value as JValue).Value;

                //如果没有找到一般的属性,则尝试查找外键属性
                for (int i = 0, c = _refIdProperties.Count; i < c; i++)
                {
                    var rip = _refIdProperties[i];
                    if (rip.Name == pName)
                    {
                        e.SetRefId(rip, rawValue);
                        break;
                    }
                }
                //只读属性。
                //if(notFound)
                //{
                //    throw new InvalidOperationException("没有在实体中找到这个属性:" + pName);
                //}
            }
        }
Пример #5
0
        /// <summary>
        /// 启用实体的幽灵(假删除)功能。
        /// </summary>
        /// <param name="meta"></param>
        public static void EnablePhantoms(this EntityMeta meta)
        {
            meta.IsPhantomEnabled = true;

            meta.Property(EntityPhantomExtension.IsPhantomProperty).MapColumn();

            //使用假删除插件后,需要把整个聚合中的所有数据都标识为‘幽灵’状态,所有的聚合子都需要在内存中也进行假删除。
            //如果在插件打开此功能后,这个功能不应该被关闭,否则会影响插件的一些功能。
            meta.DeletingChildrenInMemory = true;
        }
        private static void ProcessManagedProperties(Type type, PersistanceTableInfo table, EntityMeta em)
        {
            foreach (var property in em.EntityProperties)
            {
                var meta = property.ColumnMeta;
                if (meta == null)
                {
                    continue;
                }

                var propertyName = property.Name;

                //生成 ManagedPropertyBridge
                var epm = em.Property(propertyName);
                if (epm == null)
                {
                    throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", type.FullName, propertyName));
                }
                var mp = epm.ManagedProperty as IProperty;

                //列名
                var columnName = meta.ColumnName;
                if (string.IsNullOrWhiteSpace(columnName))
                {
                    columnName = propertyName;
                }

                var column = new PersistanceColumnInfo
                {
                    Table        = table,
                    Name         = columnName,
                    DataType     = epm.PropertyType,
                    IsIdentity   = meta.IsIdentity,
                    IsPrimaryKey = meta.IsPrimaryKey,
                    Property     = mp
                };

                if (meta.IsPrimaryKey)
                {
                    table.PKColumn = column;
                }

                table.Columns.Add(column);
            }
        }
Пример #7
0
        private static void ProcessManagedProperties(Type type, PersistanceTableInfo table, EntityMeta em)
        {
            foreach (var property in em.EntityProperties)
            {
                var meta = property.ColumnMeta;
                if (meta == null) continue;

                var propertyName = property.Name;

                //生成 ManagedPropertyBridge
                var epm = em.Property(propertyName);
                if (epm == null) { throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", type.FullName, propertyName)); }
                var mp = epm.ManagedProperty as IProperty;

                //列名
                var columnName = meta.ColumnName;
                if (string.IsNullOrWhiteSpace(columnName)) columnName = propertyName;

                var column = new PersistanceColumnInfo
                {
                    Table = table,
                    Name = columnName,
                    DataType = epm.PropertyType,
                    IsIdentity = meta.IsIdentity,
                    IsPrimaryKey = meta.IsPrimaryKey,
                    Property = mp
                };

                if (meta.IsPrimaryKey)
                {
                    table.PKColumn = column;
                }

                table.Columns.Add(column);
            }
        }
Пример #8
0
        private static void ProcessManagedProperties(
            RdbTableInfo table,
            EntityMeta em,
            IDbIdentifierQuoter identifierProvider,
            DbTypeConverter dbTypeConverter
            )
        {
            foreach (var property in em.EntityProperties)
            {
                var columnMeta = property.ColumnMeta;
                if (columnMeta == null)
                {
                    continue;
                }

                var propertyName = property.Name;

                var epm = em.Property(propertyName);
                if (epm == null)
                {
                    throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", em.EntityType.FullName, propertyName));
                }

                var columnName = identifierProvider.Prepare(columnMeta.ColumnName);

                var dbType = columnMeta.DbType ?? dbTypeConverter.FromClrType(epm.PropertyType);;
                var column = new RdbColumnInfo(columnName, epm, columnMeta, table, dbType);

                if (columnMeta.IsPrimaryKey)
                {
                    table.PKColumn = column;
                }

                table.Columns.Add(column);
            }
        }
Пример #9
0
            /// <summary>
            /// 根据实体类型创建表的描述信息,并添加到数据库中
            /// </summary>
            /// <param name="em">The memory.</param>
            /// <exception cref="System.ArgumentNullException"></exception>
            /// <exception cref="System.InvalidOperationException">refMeta.ReferenceInfo == null</exception>
            private void BuildTable(EntityMeta em)
            {
                var tableMeta = em.TableMeta;

                //视图类不需要支持数据库迁移。
                if (tableMeta.IsMappingView)
                {
                    return;
                }

                var table = new Table(tableMeta.TableName, this.Database);

                //读取实体的注释
                if (_readComment)
                {
                    table.Comment = _commentFinder.TryFindComment(em.EntityType);
                }

                var metaProperties = em.EntityProperties;

                //var managedProperties = ManagedPropertyRepository.Instance
                //    .GetTypePropertiesContainer(em.EntityType)
                //    .GetNonReadOnlyCompiledProperties();

                foreach (var property in metaProperties)
                {
                    var columnMeta = property.ColumnMeta;
                    if (columnMeta == null)
                    {
                        continue;
                    }

                    var mp = property.ManagedProperty;
                    if (mp == null)
                    {
                        throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", em.Name, mp.Name));
                    }

                    //列名
                    var propertyName = property.Name;
                    var columnName   = columnMeta.ColumnName;
                    if (string.IsNullOrWhiteSpace(columnName))
                    {
                        columnName = propertyName;
                    }

                    //类型
                    var  propertyType  = property.PropertyType;
                    bool isNullableRef = false;

                    #region 引用关系

                    if (columnMeta.HasFKConstraint)
                    {
                        var refProperty = mp as IRefProperty;
                        if (refProperty != null)
                        {
                            isNullableRef = refProperty.Nullable;

                            var refMeta = em.Property(refProperty.RefEntityProperty);
                            if (refMeta.ReferenceInfo == null)
                            {
                                throw new InvalidOperationException("refMeta.ReferenceInfo == null");
                            }

                            //引用实体的类型。
                            var refTypeMeta = refMeta.ReferenceInfo.RefTypeMeta;
                            if (refTypeMeta != null)
                            {
                                var refTableMeta = refTypeMeta.TableMeta;
                                if (refTableMeta != null)
                                {
                                    //如果主键表已经被忽略,那么到这个表上的外键也不能建立了。
                                    //这是因为被忽略的表的结构是未知的,不一定是以这个字段为主键。
                                    if (!this.Database.IsIgnored(refTableMeta.TableName))
                                    {
                                        var id = refTypeMeta.Property(Entity.IdProperty);
                                        //有时一些表的 Id 只是自增长,但并不是主键,不能创建外键。
                                        if (id.ColumnMeta.IsPrimaryKey)
                                        {
                                            this._foreigns.Add(new ForeignConstraintInfo()
                                            {
                                                FkTableName       = tableMeta.TableName,
                                                PkTableName       = refTableMeta.TableName,
                                                FkColumn          = columnName,
                                                PkColumn          = id.ColumnMeta.ColumnName,
                                                NeedDeleteCascade = refProperty.ReferenceType == ReferenceType.Parent
                                            });
                                        }
                                    }
                                }
                            }
                        }
                        else if (mp == Entity.TreePIdProperty)
                        {
                            var id = em.Property(Entity.IdProperty);
                            //有时一些表的 Id 只是自增长,但并不是主键,不能创建外键。
                            if (id.ColumnMeta.IsPrimaryKey)
                            {
                                this._foreigns.Add(new ForeignConstraintInfo()
                                {
                                    FkTableName       = tableMeta.TableName,
                                    PkTableName       = tableMeta.TableName,
                                    FkColumn          = columnName,
                                    PkColumn          = id.ColumnMeta.ColumnName,
                                    NeedDeleteCascade = false
                                });
                            }
                        }
                    }

                    #endregion

                    var dataType = TypeHelper.IgnoreNullable(propertyType);
                    //对于支持多数据类型的 Id、TreePId 属性进行特殊处理。
                    if (mp == Entity.IdProperty || mp == Entity.TreePIdProperty)
                    {
                        dataType = em.IdType;
                    }
                    var dbType = columnMeta.DataType.GetValueOrDefault(DbTypeHelper.ConvertFromCLRType(dataType));
                    var column = new Column(columnName, dbType, columnMeta.DataTypeLength, table);
                    if (columnMeta.IsRequired.HasValue)
                    {
                        column.IsRequired = columnMeta.IsRequired.Value;
                    }
                    else
                    {
                        column.IsRequired = !isNullableRef && !propertyType.IsClass && !TypeHelper.IsNullable(propertyType);
                    }
                    //IsPrimaryKey 的设置放在 IsRequired 之后,可以防止在设置可空的同时把列调整为非主键。
                    column.IsPrimaryKey = columnMeta.IsPrimaryKey;
                    column.IsIdentity   = columnMeta.IsIdentity;

                    table.Columns.Add(column);

                    //读取属性的注释。
                    if (_readComment)
                    {
                        var commentProperty = mp;
                        var refProperty     = commentProperty as IRefProperty;
                        if (refProperty != null)
                        {
                            commentProperty = refProperty.RefEntityProperty;
                        }

                        column.Comment = _commentFinder.TryFindComment(commentProperty);
                    }
                }

                table.SortColumns();

                this.AddTable(table);
            }
Пример #10
0
        private static void MapDefaultColumns(EntityMeta meta)
        {
            if (meta.TableMeta != null)
            {
                foreach (var ep in meta.EntityProperties)
                {
                    var mp = ep.ManagedProperty;
                    //Id 属性,默认的元数据中,即是主键,也是自增长列。应用层可以考虑再做配置。
                    if (mp == EntityConvention.Property_Id)
                    {
                        ep.ColumnMeta = new ColumnMeta
                        {
                            ColumnName = mp.Name,
                            IsPrimaryKey = true,
                        };
                        if (meta.IdType == typeof(int) || meta.IdType == typeof(long))
                        {
                            ep.ColumnMeta.IsIdentity = true;
                        }
                    }
                    //其它属性
                    else if (mp != EntityConvention.Property_TreeIndex && mp != EntityConvention.Property_TreePId)
                    {
                        var clrProperty = ep.CLRProperty;
                        if (clrProperty != null)
                        {
                            var columnAttri = clrProperty.GetSingleAttribute<ColumnAttribute>();
                            if (columnAttri != null)
                            {
                                var name = columnAttri.ColumnName;
                                if (string.IsNullOrWhiteSpace(name)) name = clrProperty.Name;

                                ep.ColumnMeta = new ColumnMeta { ColumnName = name };
                            }
                        }
                    }
                }

                //树的两个属性
                if (meta.IsTreeEntity)
                {
                    var p = meta.Property(EntityConvention.Property_TreeIndex);
                    if (p != null) { p.MapColumn(); }

                    p = meta.Property(EntityConvention.Property_TreePId);
                    if (p != null) { p.MapColumn(); }
                }
            }
        }
Пример #11
0
            /// <summary>
            /// 根据实体类型创建表的描述信息,并添加到数据库中
            /// </summary>
            /// <param name="em">The memory.</param>
            /// <exception cref="System.ArgumentNullException"></exception>
            /// <exception cref="System.InvalidOperationException">refMeta.ReferenceInfo == null</exception>
            private void BuildTable(EntityMeta em)
            {
                var tableMeta = em.TableMeta;

                //视图类不需要支持数据库迁移。
                if (tableMeta.IsMappingView) { return; }

                var table = new Table(tableMeta.TableName, this.Database);

                var metaProperties = em.EntityProperties;

                //var managedProperties = ManagedPropertyRepository.Instance
                //    .GetTypePropertiesContainer(em.EntityType)
                //    .GetNonReadOnlyCompiledProperties();

                foreach (var property in metaProperties)
                {
                    var columnMeta = property.ColumnMeta;
                    if (columnMeta == null) continue;

                    var mp = property.ManagedProperty;
                    if (mp == null) { throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", em.Name, mp.Name)); }

                    //列名
                    var propertyName = property.Name;
                    var columnName = columnMeta.ColumnName;
                    if (string.IsNullOrWhiteSpace(columnName)) columnName = propertyName;

                    //类型
                    var propertyType = property.PropertyType;
                    bool isNullableRef = false;

                    #region 引用关系

                    if (columnMeta.HasFKConstraint)
                    {
                        var refProperty = mp as IRefProperty;
                        if (refProperty != null)
                        {
                            isNullableRef = refProperty.Nullable;

                            var refMeta = em.Property(refProperty.RefEntityProperty);
                            if (refMeta.ReferenceInfo == null) throw new InvalidOperationException("refMeta.ReferenceInfo == null");

                            //引用实体的类型。
                            var refTypeMeta = refMeta.ReferenceInfo.RefTypeMeta;
                            if (refTypeMeta != null)
                            {
                                var refTableMeta = refTypeMeta.TableMeta;
                                if (refTableMeta != null)
                                {
                                    //如果主键表已经被忽略,那么到这个表上的外键也不能建立了。
                                    //这是因为被忽略的表的结构是未知的,不一定是以这个字段为主键。
                                    if (!this.Database.IsIgnored(refTableMeta.TableName))
                                    {
                                        var id = refTypeMeta.Property(Entity.IdProperty);
                                        //有时一些表的 Id 只是自增长,但并不是主键,不能创建外键。
                                        if (id.ColumnMeta.IsPrimaryKey)
                                        {
                                            this._foreigns.Add(new ForeignConstraintInfo()
                                            {
                                                FkTableName = tableMeta.TableName,
                                                PkTableName = refTableMeta.TableName,
                                                FkColumn = columnName,
                                                PkColumn = id.ColumnMeta.ColumnName,
                                                NeedDeleteCascade = refProperty.ReferenceType == ReferenceType.Parent
                                            });
                                        }
                                    }
                                }
                            }
                        }
                        else if (mp == Entity.TreePIdProperty)
                        {
                            var id = em.Property(Entity.IdProperty);
                            //有时一些表的 Id 只是自增长,但并不是主键,不能创建外键。
                            if (id.ColumnMeta.IsPrimaryKey)
                            {
                                this._foreigns.Add(new ForeignConstraintInfo()
                                {
                                    FkTableName = tableMeta.TableName,
                                    PkTableName = tableMeta.TableName,
                                    FkColumn = columnName,
                                    PkColumn = id.ColumnMeta.ColumnName,
                                    NeedDeleteCascade = false
                                });
                            }
                        }
                    }

                    #endregion

                    var dataType = TypeHelper.IgnoreNullable(propertyType);
                    //对于支持多数据类型的 Id、TreePId 属性进行特殊处理。
                    if (mp == Entity.IdProperty || mp == Entity.TreePIdProperty)
                    {
                        dataType = em.IdType;
                    }
                    var dbType = columnMeta.DataType.GetValueOrDefault(DbTypeHelper.ConvertFromCLRType(dataType));
                    var column = new Column(dbType, columnMeta.DataTypeLength, columnName, table);
                    if (columnMeta.IsRequired.HasValue)
                    {
                        column.IsRequired = columnMeta.IsRequired.Value;
                    }
                    else
                    {
                        column.IsRequired = !isNullableRef && !propertyType.IsClass && !TypeHelper.IsNullable(propertyType);
                    }
                    //IsPrimaryKey 的设置放在 IsRequired 之后,可以防止在设置可空的同时把列调整为非主键。
                    column.IsPrimaryKey = columnMeta.IsPrimaryKey;
                    column.IsIdentity = columnMeta.IsIdentity;

                    table.Columns.Add(column);
                }

                table.SortColumns();

                this.AddTable(table);
            }