Castle学习之二:处理主键时PrimaryKeyType.Assigned等几个有用的属性

ActiveRecord里主键是不应该被赋值的,调用ActiveRecordBase.Create()时,会自动生成一个新的主键.

如果有以下的代码:
 1     [ActiveRecord("book_School")]
 2     public class School : ActiveRecordBase<School>
 3     {
 4         Guid _id;
 5         string _name;
 6 
 7         [PrimaryKey(PrimaryKeyType.GuidComb]
 8         public Guid Id
 9         {
10             get { return _id; }
11             set { _id = value; }
12         }
13 
14         [Property(NotNull=true)]
15         public string Name
16         {
17             get { return _name; }
18             set { _name = value; }
19         }
20     }

我们在使用时,由于Id是可赋值的,很容易犯错,有没有办法让编译器保证我们没有对Id进行赋值呢?

答案是有:直接把属性Id的setter去掉就行了.

但是这样一来,ActiveRecord框架本身想要设置这个属性时就有麻烦了,它找不到setter,所以我们必须告诉它怎么设置这个属性的值:把PrimaryKeyAttribute的Access设置成PropertyAccess.FieldCamelcaseUnderscore(意思是给这个属性赋值时,如果找不到setter,就直接向名称符合以下规则的字段赋值,这个规则就是:把属性的名字转换成camelCase,然后再前面加一个下划线).这样一来,ActiveRecord向Id设置值时,发现这个属性没有setter,于是向名为_id的字段赋值.
 1     [ActiveRecord("book_School")]
 2     public class School : ActiveRecordBase<School>
 3     {
 4         Guid _id;
 5         string _name;
 6 
 7         [PrimaryKey(PrimaryKeyType.GuidComb, Access = PropertyAccess.FieldCamelcaseUnderscore)]
 8         public Guid Id
 9         {
10             get { return _id; }
11         }
12 
13         [Property(NotNull=true)]
14         public string Name
15         {
16             get { return _name; }
17             set { _name = value; }
18         }
19     }

考虑到大家的个人习惯不同,ActiveRecord还提供了FieldCamelcase (例:userId), FieldLowercaseUnderscore (例:_userid), FieldPascalcaseMUnderscore(例:m_UserId).

如果一定要手工设置主键的值,需要使用到PrimaryKeyType.Assigned.据NHibernate的文档所述:

[quote]

If you want the application to assign identifiers (as opposed to having NHibernate generate them), you may use the assigned generator. This special generator will use the identifier value already assigned to the object's identifier property. Be very careful when using this feature to assign keys with business meaning (almost always a terrible design decision).

Due to its inherent nature, entities that use this generator cannot be saved via the ISession's SaveOrUpdate() method. Instead you have to explicitly specify to NHibernate if the object should be saved or updated by calling either the Save() or Update() method of the ISession.

[/quote]

下面是综合运用以上所说的属性的代码:

School.cs

TClass.cs

这里,为了与asp.net MemberShip Provider对接, UserInfo.Id不可能由ActiveRecord自动生成,必须使用属性PrimaryKeyType.Assigned:
UserInfo.cs

Tests.cs

posted on   deerchao  阅读(2650)  评论(7编辑  收藏  举报

编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示