2012-05-13 37 views
0

我有一個表:NHibernate的3 LINQ和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; } 
} 

注意,在域模型,「模板」屬性的類型不是「串」。 模板類是這樣的:

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類?

在先進的感謝!

回答

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