我正在测试 NHibernate 以解决我公司的 ORM 需求。为此,我制作了一个基于学校的小型测试模型,为 NHibernate 处理提供了一些有用的边缘案例。
我在找出如何将自定义结构映射为实体的组件时遇到问题 不使用 IUserType
接口(interface) .我应该强调,域类与我们的 NHibernate 代码位于一个单独的程序集中是一个重要要求,并且域程序集没有对 NHibernate 的引用。
自定义结构为 Time
, 用于以小时和分钟表示一天中的某个时间。这是一个非常简单的不可变结构,仅用于说明自定义结构的问题。构造函数采用单个参数,即小时和分钟,格式为 hhmm
的整数。 .
public struct Time
{
public Time(int hoursAndMinutes)
{
// Initialize Structure //
}
public int Hours { get; private set; }
public int Minutes { get; private set; }
public int HoursAndMinutes { get; private set; }
}
此结构用作
Lesson
的组件。类来存储类(class)开始的时间:public class Lesson
{
public int ID { get; private set; }
public Teacher Teacher { get; internal set; }
public DayOfWeek Day { get; set; }
public Time StartTime { get; set; } // <-- Custom Type
public int Periods { get; set; }
}
此类直接映射到此表:
CREATE TABLE Lessons
(
ID INT,
Subject NVARCHAR(128)
TeacherID INT,
Day VARCHAR(9),
StartTime INT, // <-- Maps to custom type.
Periods INT
)
我正在寻找一种方法来将此结构映射为
Lesson
的组件。类,以便 NHibernate 将读取结构上的属性值(与任何其他组件一样)以获取列的值,但在从列到实体中。如果您有任何建议,那就太好了。如果你想告诉我这不能不使用
IUserType
来完成,这也是一个很好的答案。
最佳答案
据我所知,共有三种攻击计划。
HoursAndMinutes
属性,更改该属性的 setter 中的代码以更新 Hours
和 Minutes
适当的属性,并让构造函数调用 this.HoursAndMinutes = hoursAndMinutes;
所以更新 Hours
的代码相同和 Minutes
无论是使用构造函数还是 HoursAndMinutes
上的 setter ,属性都会被执行使用属性。如果您不使用 ORM 并且知道它会欺骗该属性,您会这样写吗?可能不是。但这不是世界末日,评论可以解释一切。 IUserType
或 ICompositeUserType
执行。确实,它们正是针对这种情况而存在的,并且可以让您灵活地在 NullSafeGet()
中随心所欲地实例化结构。在 NullSafeSet()
中实现并提取数据执行。把它放在另一个程序集中,比如 MyModel.NHibernateCrap.dll
, 如果你喜欢。您的模型/域无需知道 IUserType
实现或 NHibernate 存在——这都是映射文件指定的。 直接、真实地回答您的问题, NHibernate 不会调用有参数的构造函数,句号 ——这就是它的工作原理,它通知一个对象,然后开始设置和反射(reflect)它——除非你开始用代理做奇怪的事情或告诉它使用你的
IUserType
执行。没有机制可以说出像 <constructor><arg>HoursAndMinutes</arg></constructor>
这样的话在映射文件或类似文件中。别担心,爱炸弹。由于
IUserType
是 NHibernate 为做这些事情提供的机制,我真的不明白为什么一个人不想使用它。祝你好运!
关于nhibernate - 将不可变结构映射为 NHibernate 中的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1985002/