惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
H
Help Net Security
V
Visual Studio Blog
J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
MyScale Blog
MyScale Blog
The Cloudflare Blog
Martin Fowler
Martin Fowler
D
Docker
腾讯CDC
F
Fortinet All Blogs
雷峰网
雷峰网
GbyAI
GbyAI
G
Google Developers Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Blog — PlanetScale
Blog — PlanetScale
Engineering at Meta
Engineering at Meta
博客园 - 聂微东
博客园 - 叶小钗

博客园 - JerryZhao

[转载]jQuery对象VS DOM对象 [Reference] Navigation on Matrix Subtotal [Refereces]Creating an .ini File for the Application Manager [Refereces] Developing and Deploying Pocket PC Setup Applications [References]More on device app installs - Installing a Windows Mobile device application from a desktop MSI [References]Deploying .NET Compact Framework 2.0 Applications with .cab and .msi Files [References]Installing Multiple CAB Files [Reference]Wix Restart IIS code snippet [Reference] Windows Installer XML (WiX) 3.0 Snippets [Reference] Casle Demo App: Midway Summary [ActiveRecord] 之五:ActiveRecordMediator [Reference][ActiveRecord] 之六:继承 [Referece][ActiveRecord] 之七:多数据库配置 [Reference] [Castle AR] 5. Base Relations [Reference][Castle AR] 3. Validate [Reference][Castle AR] 2. ActiveRecord [Reference][Castle AR] 1. Starter [reference][Castle AR] 4. CRUD [Reference]NHibernateDataSource: A DataSourceControl for ASP.NET 2.0
[Reference][ActiveRecord] 之四:Cascade
JerryZhao · 2008-01-23 · via 博客园 - JerryZhao

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情况下,非级联删除时,仅会删除自身和映射表中的记录;级联删除会试图删除关联记录。

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

附:本文所有演示代码使用 2006-01-01 发布的 Castle ActiveRecord Beta3 版本。
Castle ActiveRecord 在发布 1.0 版本前可能有很多较大的变化,如演示代码无法编译,建议您参考最新版本的相关文档。