我有一张桌子:
Page (
Id int,
Name nvarchar(50),
TemplateName varchar(50)
...
)
并将其映射到域模型:
public class Page {
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Template Template { get; set; }
}
请注意,在域模型中,“Template”属性的类型不是“string”。 Template类是这样的:
public class Template {
public string Name { get; set; }
// other properties...
}
“模板”从文件系统加载。我有一个TemplateManager类:
public class TemplateManager {
public static Template LoadTemplate(string templateName) {
// check if there's a folder named <templateName>
}
}
我可以使用IUserType映射“Template”属性。
public class PageMap : ClassMapping<Page> {
public PageMap() {
...
Property(c => c.Template, m => {
m.Column("TemplateName");
m.Type<TemplateUserType>();
}
}
}
public class TemplateUserType : IUserType {
public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
{
var templateName = rs[names[0]].AsString();
if (!String.IsNullOrEmpty(templateName))
{
return TemplateManager.LoadTemplate(templateName);
}
return null;
}
}
好的,到目前为止一切顺利。但问题是,如何在Linq查询中使用Template属性? 例如:
var pages = session.Query<Page>().Where(it => it.Template.Name == "MyTemplate");
我认为解决方案可能是编写一个实现IHqlGeneratorForProperty
的类(比如TemplatePropertyHqlGenerator)。这是NHibernate 3提供的linq查询扩展点。但是如何编写这个TemplatePropertyHqlGenerator类?
先谢谢!
答案 0 :(得分:0)
IUserType
接口允许您定义被视为原子的类型。也就是说,您可以在类型的实例之间进行直接比较,NHibernate将知道如何翻译它们。
E.g。以下查询将评估:
var template = new Template();
session.Query<Page>().Where(it => it.Template == template);
如果要定义具有可以操作的组件值的类型,则需要实现ICompositeUserType
接口。此接口要求您将类型的属性定义为原子元素,为NHibernate提供了解类型特定属性所需的信息。
因此,它比IUserType
实现起来要复杂一些,但它应该促进你想要实现的目标。
以下是为Money
类型实施界面的可理解示例:http://geekswithblogs.net/opiesblog/archive/2006/08/05/87218.aspx