2011-10-27 103 views
1

我有一個映射的問題,簡化我的關係看起來像這樣。 我有父類:流利NHibernate的子類映射使用DiscriminateSubClassesOnColumn問題

public abstract class DocumentType 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
} 

和兩個子類:

public class UploadedFileDocument : DocumentType 
{ 

} 

public class ApplicationFormDocument : DocumentType 
{ 
} 

這樣映射:

public DocumentTypeMap() 
{ 
    Schema("Core"); 
    Id(x => x.Id); 
    Map(x => x.Name).Length(128).Not.Nullable(); 
    DiscriminateSubClassesOnColumn("Type"); 
} 

public class UploadedFileDocumentMap : SubclassMap<UploadedFileDocument> 
{ 

} 

public class ApplicationFormDocumentMap : SubclassMap<ApplicationFormDocument> 
{ 

} 

然後,我有一個FK另一個實體DocumentType,這樣映射:

public FileConversionMap() 
{ 
    Schema("Core"); 
    Id(x => x.Id); 
    References(x => x.Application).Not.Nullable(); 
    References(x => x.DocumentType).Not.Nullable().Fetch.Select();   
} 

我的問題是,當我取回從DB行是這樣的:

Session.Query<FileConversion>().AsQueryable(); 

所有行回來與DocumentType存在DocumentType類型,不是孩子的類型(即實際類型的屬性,即。當我做.GetType(),要麼UploadedFileDocumentApplicationFormDocument

道歉,如果這只是我昏暗。但是,我怎樣才能確定我有哪種類型的DocumentType ...是我的映射錯誤?

回答

1

當您查看生成的SQL(將.ShowSQL()添加到.Database方法中)時,是否看到輸入的類型?你應該看到類似:

INSERT 
INTO 
    "Core_DocumentType" 
    (Name, Type) 
VALUES 
    (@p0, 'ApplicationFormDocument'); 
select 
    last_insert_rowid(); 
@p0 = 'afd' [Type: String (0)] 

使用你提供的映射,它看起來不錯,我可能會返回DocumentType(使用SQLite)就好了。

下面是我用來重現它的代碼。我沒有你的FileConversion對象,所以請確認它符合你的需求。

DocumentType

public class DocumentType 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
} 

public class DocumentTypeMap : ClassMap<DocumentType> 
{ 
    public DocumentTypeMap() 
    { 
     GenerateMap(); 
    } 

    void GenerateMap() 
    { 
     Schema("Core"); 
     Id(x => x.Id).GeneratedBy.Identity(); 
     Map(x => x.Name).Length(128).Not.Nullable(); 
     DiscriminateSubClassesOnColumn("Type"); 
    } 
} 

UploadFileDocument/ApplicationFormDocument

public class UploadedFileDocument : DocumentType 
{ 
    public virtual string ContentType { get; set; } 
} 

public class ApplicationFormDocument : DocumentType 
{ 
} 

public class UploadFileDocumentMap : 
      SubclassMap<UploadedFileDocument> 
{ 
    public UploadFileDocumentMap() 
    { 
     GenerateMap(); 
    } 

    void GenerateMap() 
    { 
     Map(x => x.ContentType); 
    } 
} 

public class ApplicationFormDocumentMap : 
      SubclassMap<ApplicationFormDocument> 
{ 
} 

FileConversion

public class FileConversion 
{ 
    public virtual int Id { get; set; } 
    public virtual DocumentType DocumentType { get; set; } 
} 

public class FileConversionMap : ClassMap<FileConversion> 
{ 
    public FileConversionMap() 
    { 
     GenerateMap(); 
    } 

    void GenerateMap() 
    { 
     Schema("Core"); 
     Id(x => x.Id).GeneratedBy.Identity(); 
     References(x => x.DocumentType).Not.Nullable().Fetch.Select(); 
    } 
} 

個測試我使用(使用machine.specifications):

語境

public class when_discriminating_on_subclass 
{ 
    static IList<FileConversion> results; 
    Establish context =() => 
    { 
     using (var session = DataConfiguration.CreateSession()) 
     { 
     using (var transaction = session.BeginTransaction()) 
     { 
      var upload = new UploadedFileDocument 
          { Name = "uploaded", ContentType = "test" }; 
      var form = new ApplicationFormDocument 
          { Name = "afd" }; 
      session.Save(form); 
      session.Save(upload); 

      var formConversion = 
       new FileConversion { DocumentType = form }; 
      var uploadConversion = 
       new FileConversion { DocumentType = upload }; 
      session.Save(formConversion); 
      session.Save(uploadConversion); 

      transaction.Commit(); 
     } 
     using (var transaction = session.BeginTransaction()) 
     { 
      results = session.Query<FileConversion>().AsQueryable().ToList(); 
      transaction.Commit(); 
     } 
    } 
    }; 

規格

It should_return_two_results =() => 
    results.Count.ShouldEqual(2); 

    It should_contain_one_of_type_uploaded_file =() => 
    results 
     .Count(x => x.DocumentType.GetType() == typeof(UploadedFileDocument)) 
     .ShouldEqual(1); 

    It should_contain_one_of_type_application_form =() => 
    results 
     .Count(x => x.DocumentType.GetType() == typeof(ApplicationFormDocument)) 
     .ShouldEqual(1); 
} 

調試通過的斷言,我可以看到,收集回來與兩個類型:

DocumentType

您是否將它們轉換回映射或類中任何位置的基類型?

+0

我結束了一個不同的數據庫模式,所以一切都改變了我,但大衛的回答是非常有幫助的,我敢肯定他是對的,所以標記爲接受的答案 – soupy1976