我正在项目中使用NHibernate.dll和NHibernate.Mappings.Attributes v2.1的v2.1。
当我在下面进一步运行代码时,我得到以下异常,并将对任何指针表示感谢。在同一个项目中,如果我删除属性并使用xml映射文件,它可以正常工作。
NHibernate.MappingException was unhandled
Message="Could not compile the mapping document:
DomainModel.hbm.xml"
Source="NHibernate"
InnerException: System.NullReferenceException
Message="Object reference not set to an instance of an object."
Source="NHibernate"
StackTrace:
at NHibernate.Cfg.XmlHbmBinding.ClassBinder.BindClass
(XmlNode node, PersistentClass model)
at NHibernate.Cfg.XmlHbmBinding.RootClassBinder.Bind
(XmlNode node, HbmClass classSchema)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.AddRootClasses(XmlNode
parentNode)
at NHibernate.Cfg.XmlHbmBinding.MappingRootBinder.Bind(XmlNode node)
at NHibernate.Cfg.Configuration.AddValidatedDocument(NamedXmlDocument doc)
InnerException:
我有一个联系人类如下(Domain类只有一个方法,没有属性):
[NHibernate.Mapping.Attributes.Class]
public class Contact : DomainClass
{
[NHibernate.Mapping.Attributes.Id(Name = "Id")]
[NHibernate.Mapping.Attributes.Generator(1, Class ="Identity")]
public virtual int ID { get; set; }
[NHibernate.Mapping.Attributes.Property]
public virtual string Name { get; set; }
[NHibernate.Mapping.Attributes.Property]
public virtual string Town { get; set; }
}
和会话代码如下:
Configuration cfg = new Configuration();
cfg.Configure();
cfg.AddInputStream(NHibernate.Mapping.Attributes.HbmSerializer.Default.Serialize(
typeof(Contact).Assembly), "DomainModel.hbm.xml");
_sessionFactory=cfg.BuildSessionFactory();
我的hibernate.cfg.xml文件是:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</
property>
<property name="connection.connection_string">Server=SERVER
\EXPRESS2008;Initial Catalog=Contacts;Integrated Security=True</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFac tory, NHibernate.ByteCode.LinFu</property>
</session-factory>
</hibernate-configuration>
司徒,
据我了解,“DomainModel.hbm.xml”是NHibernate.Mappings.Attributes应该创建的文件 - 在创建文件之前发生异常(它不在输出目录中),所以很遗憾我无法发布它
答案 0 :(得分:2)
司徒,
再次感谢您的回复。
使用以下方式管理它:
using (MemoryStream stream = new MemoryStream())
{
HbmSerializer.Default.HbmNamespace = "NSpace.DomainLayer.Entities";
HbmSerializer.Default.HbmAssembly = "NSpace";
HbmSerializer.Default.Serialize(stream,
System.Reflection.Assembly.GetExecutingAssembly());
stream.Position = 0;
Configuration cfg = new Configuration();
cfg.Configure();
cfg.AddInputStream(stream);
_sessionFactory = cfg.BuildSessionFactory();
}
并在类属性中指定表名(我的疏忽因为它们与类名不同!)。
不确定为什么我们需要单独指定Namespace,因为我假设NHibernate可以计算出从程序集序列化的类型。
希望上面可以帮助任何遇到类似问题的人,虽然我的印象是很少有人使用NHibernate.Mappings.Attributes。文件似乎严重缺乏。
答案 1 :(得分:1)
如果您尚未解决问题,请尝试使用
[NHibernate.Mapping.Attributes.Class(Table="youtable",NameType=typeof(Contact ))]
public class Contact : DomainClass
{
[NHibernate.Mapping.Attributes.Id(Name = "Id")]
[NHibernate.Mapping.Attributes.Generator(1, Class ="Identity")]
public virtual int ID { get; set; }
[NHibernate.Mapping.Attributes.Property(Name="Name")]
public virtual string Name { get; set; }
[NHibernate.Mapping.Attributes.Property(Name="Town")]
public virtual string Town { get; set; }
}
我正在使用这样,它工作正常.....
答案 2 :(得分:1)
有一段时间,NHMA没有自动检测类名,因为它们现在在NHibernate中是可选的(在某些情况下,你会使用entity-name)。 但是,最新版本会恢复自动检测行为,并根据需要将其关闭。
必须手动排序属性,因为.NET在编译时不保证它(与Java不同)。
NHMA的最终目标是忠实地复制您编写XML版本的方式;所以如果你有:
<something>
<innerData/>
</something>
NHMA版本将是:
[Something]
[InnerData(2)]
NHMA试图明智地推断某些值(如名称),但只有在需要值时才会这样做。
它还提供像NameType=typeof(XXX)
这样的帮助程序,以便从智能感知,编译时验证和重构中受益。
文档中的更多详细信息: http://www.nhforge.org/doc/nh/en/index.html#mapping-attributes
答案 3 :(得分:1)
每当您使用 hbm.xml 文件时,您将设置如下配置类:
Configuration cfg = new Configuration();
cfg.Configure();
// Add class mappings to configuration object
cfg.AddAssembly(Assembly.GetCallingAssembly());
ISessionFactory sessionFactory = cfg.BuildSessionFactory();
每当你使用像classe这样的Nhibernate.Mapping.Attributes时你会使用:
例如,您在产品类
中使用Mapping.attributesConfiguration cfg = new Configuration();
cfg.Configure();
// Add class mappings attributes to configuration object
cfg.AddInputStream(HbmSerializer.Default.Serialize(typeof(Model.Product);
ISessionFactory sessionFactory = cfg.BuildSessionFactory();
答案 4 :(得分:0)
我必须说NHibnerate.Mapping.Atributes组件编写得很糟糕。 下面的代码将导致生成格式错误的映射xml
[Class()]
public class Bar{}
同时,下面的代码很好:
[Class(Name="Bar")]
public class Bar{}
此外,如果在[Id]属性之后放置[Generator]属性,那么有关生成器的信息将不会包含在xml中,但在[Id]之前放置[Generator]将完成这些工作。
3.0正在运行,我希望这些“讨厌的”错误将得到修复。
答案 5 :(得分:0)
如上所述,您必须指定类名称,因为版本2 ... 我发布了一篇关于如何通过派生HbmWriter来解决这个问题的文章:http://blog.hopla.org/2009/12/fix-for-nhibernate-mapping-attributes-2-1/
答案 6 :(得分:0)
mitjast 的答案的几乎副本,只有少量修复和格式化:
[Class(NameType = typeof(DomainClass))]
public class DomainClass
{
[NHibernate.Mapping.Attributes.Generator(Class = "guid")]
[NHibernate.Mapping.Attributes.Id(Name = "DomainID")]
public virtual Guid DomainID { get; set; }
[NHibernate.Mapping.Attributes.Property]
public virtual string Name { get; set; }
}
该定义帮助我完成所有异常并生成有效的hbm映射。 正如 Mr Cold 所提到的,生成器和 Id 属性的顺序很重要。 但在我的情况下,发现虽然对于一个类 Id 应该首先在hbm中实际提到,但对于另一个类,第一个属性应该是生成器。当我在一个类中更改这些属性的顺序以使两个类具有相同的顺序时,其中一个的hbm变得错误... 在 NHibernate.Mapping.Attributes-for-NHibernate-3.0.0.Alpha2 发布后,情况没有改变。 这种古怪事物的存在看起来足以让我不幸地转换到另一种解决方案......