Castle ActiveRecord学习实践(4):实现One-Many关系的映射  

建表
CREATE TABLE [dbo].[Employees] (
    [Employeesid] [int] IDENTITY (1, 1) NOT NULL ,
    [LogonName] [varchar] (40) COLLATE Chinese_PRC_CI_AS NULL ,
    [LastLogon] [datetime] NULL
) ON [PRIMARY]
GO

CREATE TABLE Posts (
post_id int IDENTITY(1, 1) PRIMARY KEY,
post_Employeesid int,
post_title varchar(50),
post_contents text,
post_created datetime,
)

实体类
Employees类
using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework;
using Castle.ActiveRecord.Framework.Config;
using Castle.ActiveRecord.Framework.Internal;
using Castle.ActiveRecord.Framework.Scopes;
using Castle.ActiveRecord.Framework.Validators;
using Castle.ActiveRecord.Queries.Modifiers;
using Castle.ActiveRecord.Queries;

/// <summary>
/// Employees 的摘要说明
/// </summary>

[ActiveRecord(Table="Employees")]
public class Employees : ActiveRecordBase
{
    private int _Employeesid;
    private string _LogonName;
    private DateTime _LastLogon;
    private IList _posts;

    [PrimaryKey(PrimaryKeyType.Identity, Column = "Employeesid")]
    public int Employeesid
    {
        get { return _Employeesid; }
        set { _Employeesid = value; }
    }
    [Property(Column = "LogonName")]
    public string LogonName
    {
        get { return _LogonName; }
        set { _LogonName = value; }
    }
    [Property(Column = "LastLogon")]
    public DateTime LastLogon
    {
        get { return _LastLogon; }
        set { _LastLogon = value; }
    }
    //typeof:子表实例
    //Table:子表名
    //ColumnKey:子表字段
    //Cascade:从主表到子表的级联关系:一般在主表上设为ALL
    //Inverse:控制是否反转:一般设为true,主表作为主控方
    //Lazy:是否延迟加载子表数据,主表上一般设为true,提高效率
    [HasMany(typeof(Post), Table = "Posts", ColumnKey = "post_Employeesid", Cascade = ManyRelationCascadeEnum.AllDeleteOrphan, Inverse = true, Lazy = true,BatchSize=5,Fetch=FetchEnum.SubSelect)]
    public IList Posts
    {
        get { return _posts; }
        set { _posts = value; }
    }


    #region
    public static void DeleteAll()
    {
        DeleteAll(typeof(Employees));
    }
    public static IList FindAll()
    {
        return (IList)FindAll(typeof(Employees));
    }
    public static Employees Find(int Employeesid)
    {
        return (Employees)FindByPrimaryKey(typeof(Employees), Employeesid);
    }
    #endregion
}

posts类
using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework;
using Castle.ActiveRecord.Framework.Config;
using Castle.ActiveRecord.Framework.Internal;
using Castle.ActiveRecord.Framework.Scopes;
using Castle.ActiveRecord.Framework.Validators;
using Castle.ActiveRecord.Queries.Modifiers;
using Castle.ActiveRecord.Queries;

[ActiveRecord(Table = "Posts")]
public class Post : ActiveRecordBase
{
    private int _post_id;
    private String _post_title;
    private String _post_contents;
    private DateTime _post_created;
    private Employees _employ;
    public Post()
    {
        _post_created = DateTime.Now;
    }
   
    [PrimaryKey(PrimaryKeyType.Identity, Column = "post_id")]
    public int post_id
    {
        get { return _post_id; }
        set { _post_id = value; }
    }
    [Property(Column = "post_title")]
    public String post_title
    {
        get { return _post_title; }
        set { _post_title = value; }
    }
    [Property(Column = "post_contents", ColumnType = "StringClob")]
    public String post_contents
    {
        get { return _post_contents; }
        set { _post_contents = value; }
    }
    [Property(Column = "post_created")]
    public DateTime post_created
    {
        get { return _post_created; }
        set { _post_created = value; }
    }
   
    //子表没有inverse属性;
    //Cascade:指定是否执行级联,子表指向主表的级联,一般也为None,因为一般子表删除一条数据,主表还是要保留的
    //Column:子表关联字段,它是指向主表的字段
    [BelongsTo(Column = "post_Employeesid", Cascade = CascadeEnum.None, Fetch = FetchEnum.SubSelect, Insert = true, Update = true, NotNull = true, OuterJoin = OuterJoinEnum.True)]
    public Employees empploy
    {
        get { return _employ; }
        set { _employ = value; }
    }
  
    public static void DeleteAll()
    {
        ActiveRecordBase.DeleteAll(typeof(Post));
    }
    public static Post[] FindAll()
    {
        return (Post[])ActiveRecordBase.FindAll(typeof(Post));
    }
    public static Post Find(int post_id)
    {
        return (Post)FindByPrimaryKey(typeof(Post), post_id);
    }
}


使用
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Castle;
using Castle.Core;
using Castle.ActiveRecord;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        this.GridView1.DataSource = Employees.FindAll();
        this.GridView1.DataBind();

        //增加方法一,全部利用级联关系完成,子表数据不用进行save操作
        using (TransactionScope tran = new TransactionScope())
        {
            Employees emp = new Employees();
            emp.LogonName = "test";
            emp.LastLogon = System.DateTime.Now;
            try
            {
            IList ps = new List<Post>();
            Post post = new Post();
            post.post_title = "This is my  post";
            post.post_contents = "dsffsdf";
            post.post_created = DateTime.Now;
            post.empploy = emp;//绑定关系,一定要有
            ps.Add(post);
            emp.Posts = ps;
            emp = (Employees)emp.SaveCopy();//保存并返回
            tran.VoteCommit();
            }
            catch
            {
                tran.VoteRollBack();
            }
        }

  //增加方法二,子表进行save操作,实际上这种就是没有全部利用级联的做法
 using (TransactionScope tran = new TransactionScope())
        {
            try
            {
                Employees emp = new Employees();
                emp.LogonName = "test";
                emp.LastLogon = System.DateTime.Now;
                emp = (Employees)emp.SaveCopy();//保存并返回
                //创建Post对象
                Post post = new Post();
                post.post_title = "This is my  post";
                post.post_contents = "dsffsdf";
                post.post_created = DateTime.Now;
                post.empploy = emp;//绑定关系
                post.Save();//子表数据写入
                tran.VoteCommit();
            }
            catch
            {
                tran.VoteRollBack();
            }
        }

        //修改数据
        //using (TransactionScope tran = new TransactionScope())
        //{
        //    Employees emp1 = Employees.Find(132);
        //    emp1.LogonName = "wo kao";
        //    foreach (Post p in emp1.Posts)//利用级联获取子表集合,并级联修改字表数据
        //    {
        //        p.post_title = "tttt1";
        //    }
        //    emp1.UpdateAndFlush();//更新主表数据,子表也会级联更新
        //}

        //删除主表数据,如果主表中设立了级联关系,子表数据也会删除;如果没有设,就不会删除
        //using (TransactionScope tran = new TransactionScope())
        //{
        //Employees emp1 = Employees.Find(150);
        //emp1.Delete();
        //}

        //方向关系,测试子表多主表关联,如果字表中设置了Cascade=All,那么主表数据也会删除,所以一般我们在子表中设置Cascade=None
        //Post p = Post.Find(106);
        //p.Delete();

    }
}

 

单向关联和双向关联
One-Many和Many-One互为双向关系,实际上实现这种映射就会一定存在一种双向关系

你可能感兴趣的:(Castle ActiveRecord学习实践(4):实现One-Many关系的映射  )