我遇到了映射问题,简化了我的关系。 我有父类:
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()
时, UploadedFileDocument
或ApplicationFormDocument
)
道歉,如果这只是我昏暗。但是,如何确定我所拥有的DocumentType
哪种类型......我的映射是错误的?
答案 0 :(得分: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);
}
通过断言进行调试,我可以看到该集合有两种类型:
您是否将它们转换回映射或类中任何位置的基类型?