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

推荐订阅源

宝玉的分享
宝玉的分享
NISL@THU
NISL@THU
E
Exploit-DB.com RSS Feed
L
LINUX DO - 热门话题
L
Lohrmann on Cybersecurity
K
Kaspersky official blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
T
The Exploit Database - CXSecurity.com
P
Palo Alto Networks Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threatpost
S
Schneier on Security
G
GRAHAM CLULEY
The Hacker News
The Hacker News
T
Threat Research - Cisco Blogs
Scott Helme
Scott Helme
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
P
Privacy & Cybersecurity Law Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Cyberwarzone
Cyberwarzone
C
CERT Recently Published Vulnerability Notes
T
Tor Project blog
AWS News Blog
AWS News Blog
Simon Willison's Weblog
Simon Willison's Weblog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
爱范儿
爱范儿
P
Privacy International News Feed
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
S
Securelist
G
Google Developers Blog
The Last Watchdog
The Last Watchdog
Google Online Security Blog
Google Online Security Blog
美团技术团队
F
Fortinet All Blogs
小众软件
小众软件
Recorded Future
Recorded Future
V
Visual Studio Blog
B
Blog RSS Feed
H
Help Net Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Google DeepMind News
Google DeepMind News
Blog — PlanetScale
Blog — PlanetScale
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
Martin Fowler
Martin Fowler
Latest news
Latest news
Spread Privacy
Spread Privacy
H
Heimdal Security Blog

博客园 - 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 版本前可能有很多较大的变化,如演示代码无法编译,建议您参考最新版本的相关文档。