Этот вопрос и ответ помог мне во время игры с NHibernatePets Sample
Я подумал, что мне стоит включить вышеописанную реализацию Line / Point. Мой код ниже, если кому-то интересно. Я нашел некоторые неприятные причуды с использованием атрибутов тоже. Во-первых, если вы используете несколько классов с объявлениями [Id], такими как:
[Id(Name = "id")]
[Generator(1, Class = "native")]
тогда вам нужно указать номер заказа (1) для генератора, иначе сгенерированное отображение может опустить атрибут генератора для одного или нескольких ваших классов. Очевидно, это как-то связано с тем, как VS обрабатывает вещи.
Еще одна вещь, которую я обнаружил, сравнивая образец файла Pet.hbm.xml с сгенерированным файлом, используя:
//Export to a mapping file when required. Test/Production.
HbmSerializer.Default.Serialize(typeof(Pet).Assembly,"Pets.hbm.xml");
состоял в том, что свойство Access = "field" не должно устанавливаться в атрибуте [Id], даже если оно было в файле примера сопоставления.
Линейные и UiPoint классы (в пространстве имен NHibernatePets) ...
[Class(Lazy = true)]
public class Line
{
[Id(Name = "id")]
[Generator(1, Class = "native")]
#if useAttributes
virtual public int id { get; set; }
#else
private int id;
#endif
const string point1 =
@"<component name= ""Point1"" class= ""NHibernatePets.UiPoint"" >
<property name=""X""
type=""Double""
column=""Point1_X""/>
<property name=""Y""
type=""Double""
column=""Point1_Y""/>
</component>";
const string point2 =
@"<component name=""Point2"" class=""NHibernatePets.UiPoint"" >
<property name=""X""
type=""Double""
column=""Point2_X""/>
<property name=""Y""
type=""Double""
column=""Point2_Y""/>
</component>";
[RawXml(After = typeof(ComponentAttribute), Content = point1)]
virtual public UiPoint Point1 { get; set; }
[RawXml(After = typeof(ComponentAttribute), Content = point2)]
virtual public UiPoint Point2 { get; set; }
}
//Don't need any Attributes set on this class as it's defined in the RawXml.
public class UiPoint
{
public double X { get; set; }
public double Y { get; set; }
}
In Main () ...
//Create the Line record
Line newLine = new Line
{
Point1 = new UiPoint { X = 100.1, Y = 100.2 },
Point2 = new UiPoint { X = 200.1, Y = 200.2 }
};
try
{
using (ISession session = OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(newLine);
transaction.Commit();
}
Console.WriteLine("Saved NewLine to the database");
}
}
catch (Exception e)
{ Console.WriteLine(e); }
В общеобразовательной программе ...
static ISessionFactory SessionFactory;
static ISession OpenSession()
{
if (SessionFactory == null) //not threadsafe
{ //SessionFactories are expensive, create only once
Configuration configuration = new Configuration();
#if useAttributes
{
configuration.SetDefaultAssembly("NHibernatePets");
//configuration.SetDefaultAssembly(System.Reflection.Assembly.GetExecutingAssembly().ToString());
//To use Components and other structures, AssemblyName must be set.
//configuration.SetDefaultAssembly(typeof(Pet).Assembly.ToString());
configuration.AddInputStream(NHibernate.Mapping.Attributes.HbmSerializer.Default.Serialize(typeof(Pet).Assembly));
}
#else
configuration.AddAssembly(Assembly.GetCallingAssembly());
#endif
//Export to a mapping file when required. Test/Production.
HbmSerializer.Default.Serialize(typeof(Pet).Assembly,"Pets.hbm.xml");
SessionFactory = configuration.BuildSessionFactory();
}
return SessionFactory.OpenSession();
}