NHibernate 3 Linq和IUserType

NHibernate 3 Linq和IUserType,linq,nhibernate,iusertype,Linq,Nhibernate,Iusertype,我有一张桌子: 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; } }

我有一张桌子:

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; }
}
请注意,在域模型中,“模板”属性不是“字符串”类型。 模板类如下所示:

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>
    }
}
公共类模板管理器{
公共静态模板LoadTemplate(字符串templateName){
//检查是否有名为的文件夹
}
}
我可以使用IUserType映射“模板”属性

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;
    }
}
公共类页面映射:类映射{
公共页面地图(){
...
属性(c=>c.Template,m=>{
m、 列(“模板名称”);
m、 类型();
}
}
}
公共类TemplateUserType:IUserType{
公共对象NullSafeGet(System.Data.IDataReader rs,字符串[]名称,对象所有者)
{
var templateName=rs[names[0]].AsString();
如果(!String.IsNullOrEmpty(templateName))
{
返回TemplateManager.LoadTemplate(templateName);
}
返回null;
}
}
好的,到目前为止还不错。但问题是,如何在Linq查询中使用模板属性? 对于exmaple:

var pages = session.Query<Page>().Where(it => it.Template.Name == "MyTemplate");
var pages=session.Query().Where(it=>it.Template.Name==“MyTemplate”);
我认为解决方案可能是编写一个类(比如TemplatePropertyHqlGenerator),实现
IHqlGeneratorForProperty
。这是NHibernate 3提供的linq查询扩展点。但是如何编写这个TemplatePropertyHqlGenerator类?


感谢advanced!

通过
IUserType
界面,您可以定义一个被视为原子的类型。也就是说,您可以在该类型的实例之间执行直接比较,NHibernate将知道如何翻译它们

例如,以下查询将评估:

var template = new Template();
session.Query<Page>().Where(it => it.Template == template);
var-template=新模板();
session.Query().Where(it=>it.Template==Template);
如果要定义一个具有组件值的类型,然后可以对其进行操作,则需要实现
ICompositeUserType
接口。此接口要求您将类型的属性定义为原子元素,为NHibernate提供了解类型特定属性所需的信息

因此,它的实现比IUserType稍微复杂一些,但它应该有助于实现您想要实现的目标

下面是一个为
货币
类型实现接口的可理解示例: