2011-10-27 102 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