/// <summary> /// Create a reference to another entity, this is a many-to-one relationship.<br/> /// 创建到其他实体的映射, 这是多对一的关系<br/> /// </summary> public void References <TOther>( Expression <Func <T, TOther> > memberExpression, EntityMappingOptions options) where TOther : class { ManyToOneMembers.Add(((MemberExpression)memberExpression.Body).Member); }
/// <summary> /// Maps a collection of entities as a one-to-many relationship. /// </summary> public void HasMany <TChild>( Expression <Func <T, IEnumerable <TChild> > > memberExpression, EntityMappingOptions options) where TChild : class { throw new NotSupportedException("HasMany is not supported with dapper"); }
/// <summary> /// Maps a collection of entities as a many-to-many relationship.<br/> /// 创建到实体集合的映射, 这是多对多的关系<br/> /// </summary> public void HasManyToMany <TChild>( Expression <Func <T, IEnumerable <TChild> > > memberExpression, EntityMappingOptions options = null) where TChild : class { ManyToManyMembers.Add(((MemberExpression)memberExpression.Body).Member); }
/// <summary> /// Create a reference to another entity, this is a many-to-one relationship.<br/> /// 创建到其他实体的映射, 这是多对一的关系<br/> /// </summary> public void References <TOther>( Expression <Func <T, TOther> > memberExpression, EntityMappingOptions options) where TOther : class { // Unsupported options: Length, Unique, Index, // CustomSqlType, WithSerialization options = options ?? new EntityMappingOptions(); var referenceBuilder = Builder .HasOne(memberExpression) .WithMany(GetNavigationPropertyName <TOther, IEnumerable <T> >(options)); if (!string.IsNullOrEmpty(options.Column)) { referenceBuilder = referenceBuilder.HasConstraintName(options.Column); } if (options.Nullable == true) { referenceBuilder = referenceBuilder.IsRequired(false); } else if (options.Nullable == false) { referenceBuilder = referenceBuilder.IsRequired(true); } // Cascade should specified on parent side, but just support this option if (options.CascadeDelete == false) { referenceBuilder.OnDelete(DeleteBehavior.Restrict); } else if (options.CascadeDelete == true) { referenceBuilder.OnDelete(DeleteBehavior.Cascade); } }
/// <summary> /// Create a reference to another entity, this is a many-to-one relationship.<br/> /// 创建到其他实体的映射, 这是多对一的关系<br/> /// </summary> public void References <TOther>( Expression <Func <T, TOther> > memberExpression, EntityMappingOptions options = null) where TOther : class { // Unsupported options: Length, Unique, Index, // CustomSqlType, WithSerialization, Navigation options = options ?? new EntityMappingOptions(); var manyToOnePart = base.References(memberExpression); if (!string.IsNullOrEmpty(options.Column)) { manyToOnePart = manyToOnePart.Column(options.Column); } if (options.Nullable == true) { manyToOnePart = manyToOnePart.Nullable(); } else if (options.Nullable == false) { manyToOnePart = manyToOnePart.Not.Nullable(); } // Cascade should specified on parent side, but just support this option if (options.CascadeDelete == false) { manyToOnePart.Cascade.None(); } else if (options.CascadeDelete == true) { manyToOnePart.Cascade.DeleteOrphans(); } }
/// <summary> /// Specify the primary key for this entity<br/> /// 指定实体的主键<br/> /// </summary> public void Id <TPrimaryKey>( Expression <Func <T, TPrimaryKey> > memberExpression, EntityMappingOptions options = null) { // Unsupported options: Unique, Nullable, Index, CascadeDelete options = options ?? new EntityMappingOptions(); var idPart = base.Id(Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)); if (!string.IsNullOrEmpty(options.Column)) { idPart = idPart.Column(options.Column); } if (options.Length != null) { idPart = idPart.Length(checked ((int)options.Length.Value)); } if (!string.IsNullOrEmpty(options.CustomSqlType)) { idPart = idPart.CustomSqlType(options.CustomSqlType); } if (options.WithSerialization == true) { idPart.CustomType( typeof(NHibernateJsonSerializedType <>).MakeGenericType(typeof(TPrimaryKey))); } }
/// <summary> /// Specify the primary key for this entity<br/> /// 指定实体的主键<br/> /// </summary> public void Id <TPrimaryKey>( Expression <Func <T, TPrimaryKey> > memberExpression, EntityMappingOptions options) { options = options ?? new EntityMappingOptions(); var idMap = base.Map(Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)); idMap = idMap.IsKey(); if (typeof(TPrimaryKey) == typeof(int) || typeof(TPrimaryKey) == typeof(long)) { // Recognize integer primary key as auto increment // For now there non explicit option for this idMap = idMap.IsIdentity(); } if (!string.IsNullOrEmpty(options.Column)) { idMap = idMap.ToColumn(options.Column); } if (options.WithSerialization == true) { TypeHandlerRegistrator.RegisterJsonSerializedType(typeof(TPrimaryKey)); } if (typeof(TPrimaryKey) == typeof(Guid)) { TypeHandlerRegistrator.Register(typeof(Guid), new GuidTypeHandler()); } idMember = ((MemberExpression)memberExpression.Body).Member; }
/// <summary> /// Create a reference to another entity, this is a many-to-one relationship. /// </summary> public void References <TOther>( Expression <Func <T, TOther> > memberExpression, EntityMappingOptions options) where TOther : class { throw new NotSupportedException("References is not supported with dapper"); }
/// <summary> /// Maps a collection of entities as a many-to-many relationship. /// </summary> public void HasManyToMany <TChild>( Expression <Func <T, IEnumerable <TChild> > > memberExpression, EntityMappingOptions options) where TChild : class { throw new NotSupportedException( "Entity framework core not support many-to-many yet, " + "see https://github.com/aspnet/EntityFramework/issues/1368"); }
/// <summary> /// Maps a collection of entities as a many-to-many relationship.<br/> /// 创建到实体集合的映射, 这是多对多的关系<br/> /// </summary> public void HasManyToMany <TChild>( Expression <Func <T, IEnumerable <TChild> > > memberExpression, EntityMappingOptions options = null) where TChild : class { // log error only, some functions may not work var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogError($"HasManyToMany is unsupported with dapper, expression: {memberExpression}"); }
/// <summary> /// Create a reference to another entity, this is a many-to-one relationship.<br/> /// 创建到其他实体的映射, 这是多对一的关系<br/> /// </summary> public void References <TOther>( Expression <Func <T, TOther> > memberExpression, EntityMappingOptions options) where TOther : class { // log error only, some functions may not work var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogError($"References is unsupported with dapper, expression: {memberExpression}"); }
/// <summary> /// Create a member mapping<br/> /// 创建成员映射<br/> /// </summary> public void Map <TMember>( Expression <Func <T, TMember> > memberExpression, EntityMappingOptions options = null) { // Unsupported options: CascadeDelete options = options ?? new EntityMappingOptions(); var memberPart = base.Map(Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)); var property = (PropertyInfo)((MemberExpression)memberExpression.Body).Member; if (!string.IsNullOrEmpty(options.Column)) { memberPart = memberPart.Column(options.Column); } if (options.Length != null) { memberPart = memberPart.Length(checked ((int)options.Length.Value)); } else if (property.PropertyType == typeof(string)) { memberPart = memberPart.Length(0xffff); // set max length for string by default } if (options.Unique == true) { memberPart = memberPart.Unique(); } if (options.Nullable == true) { memberPart = memberPart.Nullable(); } else if (options.Nullable == false) { memberPart = memberPart.Not.Nullable(); } if (!string.IsNullOrEmpty(options.Index)) { memberPart = memberPart.Index(options.Index); } if (!string.IsNullOrEmpty(options.CustomSqlType)) { memberPart = memberPart.CustomSqlType(options.CustomSqlType); } else if (property.PropertyType.IsEnum) { memberPart = memberPart.CustomType <int>(); // store enum as int type by default } if (options.WithSerialization == true) { memberPart.CustomType( typeof(NHibernateJsonSerializedType <>).MakeGenericType(typeof(TMember))); } }
/// <summary> /// Create a member mapping<br/> /// 创建成员映射<br/> /// </summary> public void Map <TMember>( Expression <Func <T, TMember> > memberExpression, EntityMappingOptions options) { // Unsupported options: CascadeDelete options = options ?? new EntityMappingOptions(); var propertyBuilder = Builder.Property(memberExpression); if (!string.IsNullOrEmpty(options.Column)) { propertyBuilder = propertyBuilder.HasColumnName(options.Column); } if (options.Length != null) { propertyBuilder = propertyBuilder.HasMaxLength( checked ((int)options.Length.Value)); } if (options.Unique == true) { // See http://stackoverflow.com/questions/35309553/the-property-on-entity-type-is-part-of-a-key-and-so-cannot-be-modified-or-marked Builder.HasIndex(Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)).IsUnique(); } if (options.Nullable == true) { propertyBuilder = propertyBuilder.IsRequired(false); } else if (options.Nullable == false) { propertyBuilder = propertyBuilder.IsRequired(true); } if (!string.IsNullOrEmpty(options.Index)) { Builder.HasIndex(Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)).HasName(options.Index); } if (!string.IsNullOrEmpty(options.CustomSqlType)) { propertyBuilder = propertyBuilder.HasColumnType(options.CustomSqlType); } if (options.WithSerialization == true) { // log error only, some functions may not work var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogError( "Entity framework core not support custom type mapping yet, " + "see https://github.com/aspnet/EntityFramework/issues/242 " + $"expression: {memberExpression}"); } }
/// <summary> /// Use navigation property name from options, or<br/> /// Automatic determine navigation property name on the other side<br/> /// 从选项获取导航属性名称<br/> /// 或自动检测另一端的导航属性<br/> /// </summary> protected string GetNavigationPropertyName <TOther, TNavigationType>( EntityMappingOptions options) { if (!string.IsNullOrEmpty(options.Navigation)) { return(options.Navigation); } var navigationTypeInfo = typeof(TNavigationType).GetTypeInfo(); var navigationProperty = typeof(TOther).FastGetProperties() .FirstOrDefault(p => navigationTypeInfo.IsAssignableFrom(p.PropertyType)); return(navigationProperty?.Name); }
/// <summary> /// Maps a collection of entities as a many-to-many relationship.<br/> /// 创建到实体集合的映射, 这是多对多的关系<br/> /// </summary> public void HasManyToMany <TChild>( Expression <Func <T, IEnumerable <TChild> > > memberExpression, EntityMappingOptions options) where TChild : class { // log error only, some functions may not work var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogError( "Entity framework core not support many-to-many yet, " + "see https://github.com/aspnet/EntityFramework/issues/1368 " + $"expression: {memberExpression}"); }
/// <summary> /// Create a member mapping<br/> /// 创建成员映射<br/> /// </summary> public void Map <TMember>( Expression <Func <T, TMember> > memberExpression, EntityMappingOptions options = null) { // Unsupported options: CascadeDelete options = options ?? new EntityMappingOptions(); var propertyBuilder = Builder.Property(memberExpression); if (!string.IsNullOrEmpty(options.Column)) { propertyBuilder = propertyBuilder.HasColumnName(options.Column); } if (options.Length != null) { propertyBuilder = propertyBuilder.HasMaxLength( checked ((int)options.Length.Value)); } if (options.Unique == true) { // See http://stackoverflow.com/questions/35309553/the-property-on-entity-type-is-part-of-a-key-and-so-cannot-be-modified-or-marked Builder.HasIndex(Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)).IsUnique(); } if (options.Nullable == true) { propertyBuilder = propertyBuilder.IsRequired(false); } else if (options.Nullable == false) { propertyBuilder = propertyBuilder.IsRequired(true); } if (!string.IsNullOrEmpty(options.Index)) { Builder.HasIndex(Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)).HasName(options.Index); } if (!string.IsNullOrEmpty(options.CustomSqlType)) { propertyBuilder.HasColumnType(options.CustomSqlType); } if (options.WithSerialization == true) { propertyBuilder = propertyBuilder.HasConversion( v => JsonConvert.SerializeObject(v), v => string.IsNullOrEmpty(v) ? (TMember)Activator.CreateInstance(typeof(TMember)) : JsonConvert.DeserializeObject <TMember>(v)); } }
/// <summary> /// Specify the primary key for this entity /// </summary> public void Id <TPrimaryKey>( Expression <Func <T, TPrimaryKey> > memberExpression, EntityMappingOptions options) { // Unsupported options: Length, Unique, Nullable // Index, CustomSqlType, CascadeDelete, WithSerialization options = options ?? new EntityMappingOptions(); idMember = ((MemberExpression)memberExpression.Body).Member; MapActions.Add(m => { var memberMap = m.MapIdMember(memberExpression); if (!string.IsNullOrEmpty(options.Column)) { memberMap = memberMap.SetElementName(options.Column); } }); }
/// <summary> /// Specify the primary key for this entity<br/> /// 指定实体的主键<br/> /// </summary> public void Id <TPrimaryKey>( Expression <Func <T, TPrimaryKey> > memberExpression, EntityMappingOptions options) { // Unsupported options: Length, Unique, Nullable, // Index, CustomSqlType, CascadeDelete, WithSerialization options = options ?? new EntityMappingOptions(); var keyBuilder = Builder.HasKey(Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)); if (!string.IsNullOrEmpty(options.Column)) { keyBuilder = keyBuilder.HasName(options.Column); } }
/// <summary> /// Create a member mapping<br/> /// 创建成员映射<br/> /// </summary> public void Map <TMember>( Expression <Func <T, TMember> > memberExpression, EntityMappingOptions options) { options = options ?? new EntityMappingOptions(); var memberMap = base.Map(Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)); if (!string.IsNullOrEmpty(options.Column)) { memberMap = memberMap.ToColumn(options.Column); } if (options.WithSerialization ?? false) { TypeHandlerRegistrator.RegisterJsonSerializedType(typeof(TMember)); } ordinaryMembers.Add(((MemberExpression)memberExpression.Body).Member); }
/// <summary> /// Create a member mapping<br/> /// 创建成员映射<br/> /// </summary> public void Map <TMember>( Expression <Func <T, TMember> > memberExpression, EntityMappingOptions options = null) { // Unsupported options: Length, CustomSqlType, CascadeDelete, WithSerialization options = options ?? new EntityMappingOptions(); ordinaryMembers.Add(((MemberExpression)memberExpression.Body).Member); MapActions.Add(m => { var memberMap = m.MapMember(memberExpression); if (!string.IsNullOrEmpty(options.Column)) { memberMap = memberMap.SetElementName(options.Column); } if (options.Nullable == true) { memberMap.SetIsRequired(true); } else if (options.Nullable == false) { memberMap.SetIsRequired(false); } }); if (options.Unique == true || !string.IsNullOrEmpty(options.Index)) { // Create indexes CollectionActions.Add(c => { var keys = new IndexKeysDefinitionBuilder <T>().Ascending( Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)); var indexOptions = new CreateIndexOptions() { Background = true, Unique = options.Unique, Sparse = !options.Unique // ignore null member on indexing }; var model = new CreateIndexModel <T>(keys, indexOptions); c.Indexes.CreateOne(model); }); } }
/// <summary> /// Maps a collection of entities as a one-to-many relationship.<br/> /// 创建到实体集合的映射, 这是一对多的关系<br/> /// </summary> public void HasMany <TChild>( Expression <Func <T, IEnumerable <TChild> > > memberExpression, EntityMappingOptions options) where TChild : class { // Unsupported options: Column, Length, Unique, // Nullable, Index, CustomSqlType, WithSerialization options = options ?? new EntityMappingOptions(); var collectionBuilder = Builder .HasMany(memberExpression) .WithOne(GetNavigationPropertyName <TChild, T>(options)); if (options.CascadeDelete == false) { collectionBuilder = collectionBuilder.OnDelete(DeleteBehavior.Restrict); } else { collectionBuilder = collectionBuilder.OnDelete(DeleteBehavior.Cascade); // true or default } }
/// <summary> /// Maps a collection of entities as a many-to-many relationship.<br/> /// 创建到实体集合的映射, 这是多对多的关系<br/> /// </summary> public void HasManyToMany <TChild>( Expression <Func <T, IEnumerable <TChild> > > memberExpression, EntityMappingOptions options = null) where TChild : class { // Unsupported options: Column, Length, Unique, // Nullable, Index, CustomSqlType, WithSerialization options = options ?? new EntityMappingOptions(); var manyToManyPart = base.HasManyToMany(memberExpression); if (!string.IsNullOrEmpty(options.Navigation)) { manyToManyPart.ChildKeyColumn(options.Navigation); } if (options.CascadeDelete == true) { manyToManyPart.Cascade.AllDeleteOrphan(); } else { manyToManyPart.Cascade.None(); // false or default } }
/// <summary> /// Specify the primary key for this entity /// </summary> public void Id <TPrimaryKey>( Expression <Func <T, TPrimaryKey> > memberExpression, EntityMappingOptions options) { options = options ?? new EntityMappingOptions(); var idMap = base.Map(Expression.Lambda <Func <T, object> >( Expression.Convert(memberExpression.Body, typeof(object)), memberExpression.Parameters)); idMap = idMap.IsKey(); if (!string.IsNullOrEmpty(options.Column)) { idMap = idMap.ToColumn(options.Column); } if (options.WithSerialization == true) { TypeHandlerRegistrator.RegisterJsonSerializedType(typeof(TPrimaryKey)); } if (typeof(TPrimaryKey) == typeof(Guid)) { TypeHandlerRegistrator.Register(typeof(Guid), new GuidTypeHandler()); } idMember = ((MemberExpression)memberExpression.Body).Member; }
/// <summary> /// Specify the primary key for this entity<br/> /// 指定实体的主键<br/> /// </summary> public void Id <TPrimaryKey>( Expression <Func <T, TPrimaryKey> > memberExpression, EntityMappingOptions options) { IdMember = ((MemberExpression)memberExpression.Body).Member; }
/// <summary> /// Create a member mapping<br/> /// 创建成员映射<br/> /// </summary> public void Map <TMember>( Expression <Func <T, TMember> > memberExpression, EntityMappingOptions options) { OrdinaryMembers.Add(((MemberExpression)memberExpression.Body).Member); }