Skip to content

Fluent mapping

shuxin edited this page Oct 30, 2023 · 5 revisions

Fluent mapping

Chloe.ORM 除了使用特性的方式配置映射关系外,还支持 Fluent mapping。

个人建议使用 Fluent mapping,因为 Fluent mapping 使得实体更加纯粹,而且更方便支持或移植其它数据库。

1. 创建实体

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Gender? Gender { get; set; }
    public int? Age { get; set; }
    public int? CityId { get; set; }

    public DateTime CreateTime { get; set; } = DateTime.Now;
    public DateTime? EditTime { get; set; }

    public string NotMapped { get; set; }

    //[Column(IsRowVersion = true)]
    //public int RowVersion { get; set; }
    
    public PersonEx Ex { get; set; } /* 1:1 */
    public City City { get; set; }
public class PersonEx
{
    public Person Owner { get; set; }  /* 1:1 */

    public int Id { get; set; }
    public string IdNumber { get; set; }
    public DateTime? BirthDay { get; set; }
}
public class City
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int ProvinceId { get; set; }

    public Province Province { get; set; }

    public List<Person> Persons { get; set; } = new List<Person>();
}
public class Province
{
    public int Id { get; set; }
    public string Name { get; set; }

    public List<City> Cities { get; set; } = new List<City>();
}

2. 创建映射关系

创建继承于 Chloe.Entity.EntityTypeBuilder 的类。

public class PersonMap : EntityTypeBuilder<Person>
{
    public PersonMap()
    {
        this.MapTo("Person");
        this.Property(a => a.Id).IsAutoIncrement().IsPrimaryKey();
        this.Property(a => a.Gender).HasDbType(DbType.Int32);
        this.Property(a => a.CreateTime).UpdateIgnore(); //更新实体时不更新此字段

        /* 配置导航属性关系 */
        this.HasOne(a => a.Ex).WithForeignKey(a => a.Id);
        this.HasOne(a => a.City).WithForeignKey(a => a.CityId);

        this.Ignore(a => a.NotMapped); //不映射任何字段

        /* global filter */
        //this.HasQueryFilter(a => a.Id > -1);
    }
}
public class PersonExMap : EntityTypeBuilder<PersonEx>
{
    public PersonExMap()
    {
        this.MapTo("PersonEx");
        this.Property(a => a.Id).IsPrimaryKey().IsAutoIncrement(false);

        /* 配置导航属性关系 */
        this.HasOne(a => a.Owner).WithForeignKey(a => a.Id);

        /* global filter */
        //this.HasQueryFilter(a => a.Id > -1);
    }
}

public class CityMap : EntityTypeBuilder<City>
{
    public CityMap()
    {
        this.Property(a => a.Id).IsAutoIncrement().IsPrimaryKey();

        /* 配置导航属性关系 */
        this.HasMany(a => a.Persons);
        this.HasOne(a => a.Province).WithForeignKey(a => a.ProvinceId);

        //this.HasQueryFilter(a => a.Id > -2);
    }
}

public class ProvinceMap : EntityTypeBuilder<Province>
{
    public ProvinceMap()
    {
        this.Property(a => a.Id).IsAutoIncrement().IsPrimaryKey();

        /* 配置导航属性关系 */
        this.HasMany(a => a.Cities);

        //this.HasQueryFilter(a => a.Id > -3);
    }
}

3. 注册 EntityMap

在应用程序启动时注册 EntityMap。

DbConfiguration.UseTypeBuilders(typeof(PersonMap));
DbConfiguration.UseTypeBuilders(typeof(PersonExMap));
DbConfiguration.UseTypeBuilders(typeof(CityMap));
DbConfiguration.UseTypeBuilders(typeof(ProvinceMap));

更多 fluent mapping 的用法请参考 https://github.com/shuxinqin/Chloe/tree/master/src/ChloeDemo