我有一个现有的课程,我想按原样坚持。
class Foo
{
public int Id;
...
}
我有以下ClassMap:
class FooMap : ClassMap<Foo>
{
Id(x => x.Id);
...
}
构建会话工厂会导致无效的强制转换异常。如果我的实体类具有标准的“public virtual int Id {get; private set;}”属性,则我的设置有效。我有兴趣学习是否可以使用“public int Id”字段作为nhibernate Id。
修改
看起来你现在无法用FluentNHibernate做到这一点,因为它总是处理属性。这可以通过混合NHibernate xml映射来完成。 Details on the mailing list
答案 0 :(得分:2)
如果指定不应使用类级别的延迟加载(即,NHibernate不应为对象创建代理),则不必将所有属性设置为虚拟。
默认情况下,NHibernate在从数据库中检索实体实例时会创建代理。也就是说,它返回一个'空'对象,只为其填充了Id字段。 仅当您需要该对象的任何其他属性时,才会检索该对象本身。
如果您不想要此行为,可以通过在类级别指定“lazy = false”将其关闭。 使用hbm - 映射文件,您可以这样做:
<class name="MyClass" table="sometable" lazy="false">
</class>
但是,我不知道如何在Fluent中这样做;我还没有流利地玩过。
编辑: 无论如何,NHibernate必须有办法设置字段。为此,您有两个选择:
第二个选项不是使用自动属性,而是像这样创建你的属性:
public class MyClass
{
private int _id;
public int Id { get { return _id; } }
}
然后,在映射中,您必须定义NHibernate在设置其值时应使用支持字段而不是属性。 在一个hbm映射文件中,你这样做:
<property name="Id" column="columnname" access="field.camelcase-underscore" />
正如您所看到的,您指定NHibernate应该使用该字段,并且它可以通过应用给定的命名策略来查找字段。 (在这种情况下,该字段与属性具有相同的名称,但它以下划线为前缀,并使用camelcase(第一个字符为小写)编写。 (对于身份,它应该也有效:
<id name="Id" column="..." access="field.camelcase-underscore" />
<generator ... />
</id>
为了映射字段而不是属性,您只需要定义
access="field"
在映射文件中。但同样,我不知道如何使用Fluent ...猜猜我迫不及待地想看看Fluent。
修改强> 好的,我已经下载了Fluent。 :) 是不是可以这样做:
public class FooMap : ClassMap<Foo>
{
public FooMap()
{
Id( x => x.Id).Access.Field ();
}
}
答案 1 :(得分:1)
我也在邮件列表上回答了这个问题(它是cross posted there),但我认为在这里澄清也是有用的。
不幸的是,Fluent NHibernate目前假设您传递的是一个引用属性的lambda表达式(这种假设表现为对PropertyInfo类型的严重依赖)。因此,如果Id是字段而不是属性,则此行将在运行时失败:
Id( x => x.Id).Access.Field();
我们打算通过消除对PropertyInfo的依赖来最终解决这个问题。