[Castle ActiveRecord ] 5. Base Relations

本文介绍 Castle ActiveRecord 中的数据关联处理方式,包括 One-to-Many、Many-to-One 和 Many-to-Many 关系的实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Castle ActiveRecord 通过特性处理数据表关联关系。
  • Many-to-one: BelongsToAttribute
  • One-to-many: HasManyAttribute
  • Many-to-many: HasAndBelongsToManyAttribute
1. One-to-Many / Many-to-One

多数时候,Many-to-One 和 One-To-Many 总算相伴而生的。在下面的例子中,每个组可以有多个用户加入。我们通过在 User 类型里面使用 BelongsTo 添加一个名为 "GroupId" 的字段来处理 Many-to-One 的关联,而在 Group 中我们使用 HasMany 处理 One-to-Many。注意 HasMany 的参数,分别是 "User 类型对象","BelongsTo 所定义的字段名",以及 "User 的表名"。当然,我们可以直接缩写成 HasMany(typeof(User), "GroupId", "Users") 。
[ActiveRecord("Groups")]
public class Group : ActiveRecordBase<Group>
{
    private int id;

    [PrimaryKey(PrimaryKeyType.Identity)]
    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    private string name;

    [Property(Unique = true, NotNull = true)]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    private IList users = new List<User>();

    [HasMany(typeof(User), ColumnKey = "GroupId", Table = "Users")]
    public IList Users
    {
        get { return users; }
        set { users = value; }
    }
}

[ActiveRecord("Users")]
public class User : ActiveRecordBase<User>
{
    private int id;

    [PrimaryKey(PrimaryKeyType.Identity)]
    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    private string name;

    [Property(Unique = true, NotNull = true)]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    private Group group;

    [BelongsTo("GroupId")]
    public Group Group
    {
        get { return group; }
        set { group = value; }
    }
}

public class ARTester
{
    public static void Test()
    {
        ActiveRecordStarter.Initialize(Assembly.GetExecutingAssembly(), new XmlConfigurationSource("ar.xml"));
        ActiveRecordStarter.DropSchema();
        ActiveRecordStarter.CreateSchema();

        Group group = new Group();
        group.Name = "Group1";
        group.Save();

        for (int i = 0; i < 10; i++)
        {
            User user = new User();
            user.Name = "User" + i;
            user.Group = group;
            user.Save();
        }

        // ---------------

        foreach (User _user in Group.FindAllByProperty("Name", "Group1")[0].Users)
        {
            Console.WriteLine("{0},{1}", _user.Name, _user.Group.Name);
        }
    }
}


数据表关系图

Group 表

User 表

如果我们想将 HasMany 改成强类型,需要额外下载 NHibernate Generics,详细代码可参考 "Generics support"。

2. Many-to-Many

Many-to-Many 是通过额外的映射表来建立关联关系的。注意 HasAndBelongsToMany 的参数,分别是 "关联目标类型"、"映射表名"、"本类型在映射表中主键字段名(ColumnKey)"、"关联类型在映射表中主键字段名(ColumnRef)"。两个关联类型的相关参数必须一致。

我们修改一下上面的例子,让用户可以同时加入多个组,这样就实现了 Many-to-Many 的需求。

[ActiveRecord("Groups")]
public class Group : ActiveRecordBase<Group>
{
    private int id;

    [PrimaryKey(PrimaryKeyType.Identity)]
    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    private string name;

    [Property(Unique = true, NotNull = true)]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    private IList users = new List<User>();

    [HasAndBelongsToMany(typeof(User), Table = "UserGroup", ColumnKey = "GroupId", ColumnRef = "UserId")]
    public IList Users
    {
        get { return users; }
        set { users = value; }
    }
}

[ActiveRecord("Users")]
public class User : ActiveRecordBase<User>
{
    private int id;

    [PrimaryKey(PrimaryKeyType.Identity)]
    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    private string name;

    [Property(Unique = true, NotNull = true)]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    private IList groups;

    [HasAndBelongsToMany(typeof(Group), Table = "UserGroup", ColumnKey = "UserId", ColumnRef = "GroupId")]
    public IList Groups
    {
        get { return groups; }
        set { groups = value; }
    }
}

public class ARTester
{
    public static void Test()
    {
        ActiveRecordStarter.Initialize(Assembly.GetExecutingAssembly(), new XmlConfigurationSource("ar.xml"));
        ActiveRecordStarter.DropSchema();
        ActiveRecordStarter.CreateSchema();

        for (int i = 0; i < 10; i++)
        {
            User user = new User();
            user.Name = "User" + i;
            user.Save();
        }

        for (int i = 0; i < 10; i++)
        {
            Group group = new Group();
            group.Name = "Group" + i;
            group.Save();
        }

        User user1 = User.FindAllByProperty("Name", "User1")[0];
        user1.Groups.Add(Group.FindAllByProperty("Name", "Group1")[0]);
        user1.Groups.Add(Group.FindAllByProperty("Name", "Group2")[0]);
        user1.Groups.Add(Group.FindAllByProperty("Name", "Group3")[0]);
        user1.Save();

        Group group1 = Group.FindAllByProperty("Name", "Group1")[0];
        group1.Users.Add(User.FindAllByProperty("Name", "User7")[0]);
        group1.Users.Add(User.FindAllByProperty("Name", "User8")[0]);
        group1.Save();

        // ------------

        foreach (Group g in User.FindAllByProperty("Name", "User1")[0].Groups)
        {
            Console.WriteLine(g.Name);
        }

        foreach (User u in Group.FindAllByProperty("Name", "Group1")[0].Users)
        {
            Console.WriteLine(u.Name);
        }
    }
}



数据表关系图

User 表

Group 表

UserGroup 表

通过上面的图,我们发现 "ActiveRecordStarter.CreateSchema()" 创建的映射表(UserGroup)并不会创建组合主键,加上我们使用 IList 存储关联对象,因此可能会出现关联对象重复问题。解决的方法是使用自定义类型或者字典来替换 IList。

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值