可选的 SubclassMap(左连接)与 NHibernate 3.0 GA &联邦健康局
免责声明:我对 NH & 还很陌生。一般而言,ORM。
免责声明:我正在使用 此处 构建的 FNH,以便与 NH3.0GA 一起使用。
简而言之,问题是我想使用 FNH 的 SubclassMap 作为将 LEFT JOIN、每个子类一个表的场景映射到我的对象层次结构的方法,该对象层次结构定义为:
public class MyBaseClass {
public virtual int Id { get; set; }
}
public class MySubClass : MyBaseClass {
public virtual string SubClassVal { get; set; }
}
这是通过 FNH 映射的as:
public class MyBaseClassMap : ClassMap<MyBaseClass> {
public MyBaseClassMap() {
Table("BaseClass");
Id(x => x.Id, "Id").GeneratedBy.Assigned();
}
}
public class MySubClassMap : SubclassMap<MySubClass> {
public MySubClassMap() {
Table("SubClass");
KeyColumn("Id");
Map(x => x.SubClassVal);
}
}
我通过以下方式检索:
public class Repository {
ISession session; //assume properly initialized ISession
public IList<T> GetAll<T>() where T: class {
return session.CreateCriteria<T>().List<T>();
}
}
在我的数据库中,我的BaseClass
表中有1条记录,SubClass
中有0条记录。
现在,我想做的是通过执行以下操作将实体作为 MySubClass
实例拉出:
var rep = new Repository();
var subclasses = rep.GetAll<MySubClass>();
当然,返回的集合中没有实例,因为这可能正在执行 INNER JOIN在这一切之下。这就是我被困住的地方。我设法发现指定“可选”连接正是我应该做的事情。我尝试将 MySubClassMap
修改为:
public class MySubClassMap : SubclassMap<MySubClass> {
public MySubClassMap() {
Join("SubClass", j => {
j.KeyColumn("Id");
j.Optional();
j.Map(x => x.SubClassVal); // note that I've tried the map outside the Join() below, to no avail
});
//Map(x => x.SubClassVal);
}
}
编译/运行此代码会出现以下(最内部)异常:
名称空间“urn:nhibernate-mapping-2.2”中的元素“joined-subclass”无效命名空间“urn:nhibernate-mapping-2.2”中的子元素“join”。预期可能元素的列表:“属性、多对一、一对一、组件、动态组件、属性、任意、映射、集合、列表、包、idbag、数组、基元数组、连接子类” 、 loader、sql-insert、sql-update、sql-delete、结果集、查询、sql-query' 位于命名空间 'urn:nhibernate-mapping-2.2' 中。
我将保存发布堆栈跟踪,但其要点是:
MyApp -->
FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() -->
NHibernate.Cfg.FluentConfiguration.BuildConfiguration()
我认为这就是所有相关信息。我怀疑我可能会遇到这个非常新的 NH 版本和不太新的 FNH 版本之间的重大变化。但是,正如前面提到的,我是一个菜鸟,很可能会做一些愚蠢的事情。如果是这样的话,我会非常感激有人用可能显而易见的东西来敲我的头。
提前致谢。
Disclaimer: I'm fairly new to NH & ORM in general.
Disclaimer: I'm working with a build of FNH from here in order to use with NH3.0GA.
The problem in a nutshell is that I would like to use FNH's SubclassMap
as a way to map a LEFT JOIN, table-per-subclass scenario to my object hierarchy which is defined as:
public class MyBaseClass {
public virtual int Id { get; set; }
}
public class MySubClass : MyBaseClass {
public virtual string SubClassVal { get; set; }
}
This is mapped via FNH as:
public class MyBaseClassMap : ClassMap<MyBaseClass> {
public MyBaseClassMap() {
Table("BaseClass");
Id(x => x.Id, "Id").GeneratedBy.Assigned();
}
}
public class MySubClassMap : SubclassMap<MySubClass> {
public MySubClassMap() {
Table("SubClass");
KeyColumn("Id");
Map(x => x.SubClassVal);
}
}
And I retrieve via:
public class Repository {
ISession session; //assume properly initialized ISession
public IList<T> GetAll<T>() where T: class {
return session.CreateCriteria<T>().List<T>();
}
}
And in my database, I've got 1 record in my BaseClass
table, 0 records in SubClass
.
Now, what I would like to do is pull the entity out as a MySubClass
instance by doing something like this:
var rep = new Repository();
var subclasses = rep.GetAll<MySubClass>();
And of course, there are no instances in the returned collection as this is presumably performing an INNER JOIN underneath it all. This is where I'm stuck. I've managed to discover that specifying an 'optional' join is what I'm supposed to do. I've attempted to modify MySubClassMap
to:
public class MySubClassMap : SubclassMap<MySubClass> {
public MySubClassMap() {
Join("SubClass", j => {
j.KeyColumn("Id");
j.Optional();
j.Map(x => x.SubClassVal); // note that I've tried the map outside the Join() below, to no avail
});
//Map(x => x.SubClassVal);
}
}
Compiling/running this presents me with the following (innermost) exception:
The element 'joined-subclass' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'join' in namespace 'urn:nhibernate-mapping-2.2'. List of possible elements expected: 'property, many-to-one, one-to-one, component, dynamic-component, properties, any, map, set, list, bag, idbag, array, primitive-array, joined-subclass, loader, sql-insert, sql-update, sql-delete, resultset, query, sql-query' in namespace 'urn:nhibernate-mapping-2.2'.
I'll save posting the stack trace, but the jist of it is:
MyApp -->
FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() -->
NHibernate.Cfg.FluentConfiguration.BuildConfiguration()
I think that's all the relevant info. I suspect I may be bumping into a breaking change between this very new version of NH and version of FNH that isn't so new. But, as mentioned earlier, I am a rookie, and could well be doing something stupid. If this is the case, I'd very much appreciate somebody smacking me over the head with what probably should be obvious.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实体只有一种类型,且不会改变。如果您的 BaseClass 表中只有一条记录,则该实体现在是并且将始终是 MyBaseClass。
如果实体可以更改其“类型”,则不应使用继承,而应使用组合。
Entities have one type, which doesn't change. If you have a record in your BaseClass table only, that entity is and will always be a MyBaseClass.
If entities can change their "type", you shouldn't use inheritance but composition.