0

我有一张桌子:

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>
    }
}

我可以使用 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;
    }
}

好的,到目前为止一切顺利。但问题是,如何在 Linq 查询中使用 Template 属性?例如:

var pages = session.Query<Page>().Where(it => it.Template.Name == "MyTemplate");

我认为解决方案可能是编写一个类(比如 TemplatePropertyHqlGenerator)实现IHqlGeneratorForProperty. 这是NHibernate 3提供的linq查询扩展点。但是这个TemplatePropertyHqlGenerator类怎么写呢?

先谢谢了!

4

1 回答 1

0

IUserType接口允许您定义一种被认为是原子的类型。也就是说,您可以在类型的实例之间进行直接比较,NHibernate 将知道如何翻译它们。

例如,以下查询将评估:

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

于 2012-05-13T11:11:04.423 回答