у нас есть старое, большое приложение asp.net с nhibernate, которое мы расширяем и модернизируем некоторые его части. Использованный NHibernate был довольно стар (1.0.2.0), поэтому мы решили обновить его до (2.1.2) для новых функций. Файлы HBM генерируются через пользовательский шаблон с MyGeneration. Все прошло довольно гладко, кроме одного.
Допустим, у нас есть объекты Blog и Post. В блоге может быть много постов, поэтому пост будет иметь отношения один-на-один. Благодаря тому, как работает это приложение, связь осуществляется не через первичные ключи, а через столбец Blog.Reference.
Примеры карт и .cs файлов:
<?xml version="1.0" encoding="utf-8" ?>
<id name="Id" column="Id" type="Guid">
<generator class="assigned"/>
</id>
<property column="Reference" type="Int32" name="Reference" not-null="true" />
<property column="Name" type="String" name="Name" length="250" />
</class>
<?xml version="1.0" encoding="utf-8" ?>
<id name="Id" column="Id" type="Guid">
<generator class="assigned"/>
</id>
<property column="Reference" type="Int32" name="Reference" not-null="true" />
<property column="Name" type="String" name="Name" length="250" />
<many-to-one name="Blog" column="BlogId" class="SampleNamespace.BlogEntity,SampleNamespace" property-ref="Reference" />
</class>
И файлы классов
class BlogEntity
{
public Guid Id { get; set; }
public int Reference { get; set; }
public string Name { get; set; }
}
class PostEntity
{
public Guid Id { get; set; }
public int Reference { get; set; }
public string Name { get; set; }
public BlogEntity Blog { get; set; }
}
Теперь допустим, что у меня есть блог с идентификатором 1D270C7B-090D-47E2-8CC5-A3D145838D9C и со ссылкой 1
В старом nhibernate такое было возможно:
//this Blog already exists in database
BlogEntity blog = new BlogEntity();
blog.Id = Guid.Empty;
blog.Reference = 1; //Reference is unique, so we can distinguish Blog by this field
blog.Name = "My blog";
//this is new Post, that we are trying to insert
PostEntity post = new PostEntity();
post.Id = Guid.NewGuid();
post.Name = "New post";
post.Reference = 1234;
post.Blog = blog;
session.Save(post);
Однако в новой версии я получаю исключение, которое не может вставить NULL в Post.BlogId. Как я понимаю, в старой версии для nhibernate было достаточно иметь поле Blog.Reference, и оно могло бы извлекать сущность по этому полю и прикреплять его к PostEntity, и при сохранении PostEntity все будет работать правильно. И, как я понимаю, новый NHibernate пытается получить только по Blog.Id.
Как это решить? Я не могу изменить дизайн БД и не могу назначить Id для BlogEntity, так как объекты находятся вне моего контроля (они предварительно заполнены как общие «объекты», подобные этому из внешнего источника)