• [ActiveRecord] 之Cascade


    http://www.rainsts.net/article.asp?id=242
    在ActiveRecord中级联操作为我们带来很多方便,但是一些细节地方需要注意。

    [ActiveRecord("Users")]
    public class User : ActiveRecordBase
    {
      public User()
      {
      }

      public User(string name) : this()
      {
        this.name = name;
      }

      private int id;

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

      private string name;

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

      private Company company;

      [BelongsTo("CompanyId")]
      public Company Company
      {
        get { return company; }
        set { company = value; }
      }
    }

    [ActiveRecord("company")]
    public class Company : ActiveRecordBase
    {
      public Company()
      {
      }

      public Company(string name) : this()
      {
        this.name = name;
      }

      private int id;

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

      private string name;

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

      private IList users = new ArrayList();

      [HasMany(typeof(User), ColumnKey = "CompanyId", Table = "Users", Cascade=ManyRelationCascadeEnum.AllDeleteOrphan)]
      public IList Users
      {
        get { return users; }
        set { users = value; }
      }

      public static Company Find(int id)
      {
        return FindByPrimaryKey(typeof(Company), id) as Company;
      }
    }


    在上面的代码中我们为 Company.Users 添加了级联操作属性。接下来我们分别验证一下在级联(Cascade=ManyRelationCascadeEnum.AllDeleteOrphan)和非级联(Cascade=ManyRelationCascadeEnum.None)方式下操作对象有什么不同。。

    1. 级联方式插入:创建Company和其关联的用户,company.Create() 会自动保存company.Users中的关联对象。

    using (TransactionScope trans = new TransactionScope())
    {
      try
      {
        Company company = new Company("公司A");

        for (int i = 1; i <= 10; i++)
        {
          User user = new User("用户" + i);
          company.Users.Add(user);
        }

        company.Create();
        trans.VoteCommit();
      }
      catch
      {
        trans.VoteRollBack();
      }
    }


    2. 级联方式删除:删除Company对象时,其关联的User对象也正常被删除。

    Company company = Company.Find(1);
    company.Delete();


    3. 级联方式删除:可以通过移除 Company.User 集合中的 User 对象的方式来删除 User 对象。

    Company company = Company.Find(1);
    company.Users.RemoveAt(2);
    company.Update();


    4. 非级联方式插入:必须先创建(保存)Company对象,而且需要指定 User.Company 属性才能正确创建所有对象。

    using (TransactionScope trans = new TransactionScope())
    {
      try
      {
        Company company = new Company("公司A");
        company.Create();

        for (int i = 1; i <= 10; i++)
        {
          User user = new User("用户" + i);
          user.Company = company;
          user.Save();
        }

        trans.VoteCommit();
      }
      catch
      {
        trans.VoteRollBack();
      }
    }


    5. 非级联方式删除:仅删除了Company对象自身,与之关联的User对象并未被删除,仅将其CompanyId字段设为NULL。

    Company company = Company.Find(1);
    company.Delete();


    6. 非级联方式删除:移除集合中子对象时,也并未真正将其删除,同样只是将其CompanyId字段设为NULL而已。

    Company company = Company.Find(1);
    company.Users.RemoveAt(2);
    company.Update();


    正确的做法

    (company.Users[2] as User).Delete();


    可见两种方式操作上有很大差异,编码时一定要注意,否则数据库中恐怕会留下许多“僵尸”数据。

    ------------------

    在ManyToMany情况下,非级联删除时,仅会删除自身和映射表中的记录;级联删除会试图删除关联记录。

  • 相关阅读:
    shell脚本
    恋练有词
    sublime text3 的汉化
    c#中如何将int i=1;转化成string s="0001"
    SQL语句中DateAdd 函数说明
    ASP.NET弹出对话框
    C/C++避免头文件包含造成的重定义方法
    Android:保存图片到Sqlite数据库
    Ubuntu 12.04 配置
    C# 实现天气预报
  • 原文地址:https://www.cnblogs.com/easyleo/p/3193862.html
Copyright © 2020-2023  润新知