获取NHibernate.Mappings.Attributes以工作选项

时间:2009-04-24 14:40:26

标签: nhibernate attributes nhibernate-mapping

我正在项目中使用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应该创建的文件 - 在创建文件之前发生异常(它不在输出目录中),所以很遗憾我无法发布它

7 个答案:

答案 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.attributes
Configuration 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 发布后,情况没有改变。 这种古怪事物的存在看起来足以让我不幸地转换到另一种解决方案......