Свободный NHibernate: нарушение внешнего ключа или нулевые значения - PullRequest
0 голосов
/ 14 июня 2010

Эй, ребята, у меня есть некоторые реальные проблемы с отображением с использованием беглого nhibernate.Я понимаю, что на этом сайте и многих других есть много постов, посвященных определенным типам картирования, но пока я не нашел решения, которое решает мою проблему.

Вот что у меня есть:

namespace MyProject.Models.Entites
{
    public class Project
    {
       public virtual Guid Id {get; set;}
       // A load of other properties
       public virtual ProjectCatagory Catagory{get;set;}           
    }
}

, а затем карта:

namespace MyProject.DataAccess.ClassMappings
{
    public class ProjectMap : ClassMap<Project>
    {
        public ProjectMap()
        {
            Id(x => x.Id);
            Map(x => x.Title);
            Map(x => x.Description);
            Map(x => x.LastUpdated);
            Map(x => x.ImageData).CustomSqlType("image");
            HasOne(x => x.Catagory);           
        }
    }
}

Итак, как вы можете видеть, у меня есть проект, который содержит свойство категории.Я не очень разбираюсь в реляционных базах данных, но, насколько я могу судить, это отношения «многие-один», когда у многих проектов может быть одна категория.Нет, проекты не могут быть отнесены к более чем одной категории.

Итак, теперь у нас есть:

namespace MyProject.Models.Entities
{
   public class ProjectCatagory
   {
        public virtual Guid Id { get; set; }
        public virtual String Name { get; set; }
   }
}

и его карта:

public ProjectCatagoryMap()
{
    Id(x => x.Id);
    Map(x => x.Name);
}

Проблема в том, что этоне работает!В модульном тесте я сделаю что-то похожее на следующее:

Project myproject = new Project("Project Description");
// set the other properties
myProject.Catagory = new ProjectCatagory(Guid.New(), "Test Catagory");
repository.Save(myProject);

Теперь я попробовал несколько картографических конфигураций и конфигураций базы данных, пытаясь заставить это работать.В настоящее время в таблице базы данных Project есть столбец "Catagory_id" (который я не поместил туда, я предполагаю, что NH добавил его в результате сопоставления), и мне хотелось бы, чтобы он был установлен, чтобы не допускать нулевые значения.Однако, когда он установлен как таковой, я получаю исключения, объясняющие, что я не могу вставить нулевые значения в таблицу (хотя во время отладки я проверил все свойства объекта Project, и они НЕ являются нулевыми).

В качестве альтернативы, я могу разрешить таблице принимать пустые значения в этом столбце, и она просто сохранит объект Project и полностью игнорирует свойство Category при сохранении, поэтому при получении проверяет, имеет ли правильная категориябыло связано с неудачей проекта.

Если я правильно помню, в какой-то момент у меня было использование ProjectMap:

References(x => x.Catagory).Column("Catagory_id").Cascade.All().Not.Nullable();

это изменило исключение из "Не могу вставить нулевые значения" в чужойКлючевое нарушение.

Я подозреваю, что корень всех этих проблем возникает из-за моего непонимания настройки реляционной базы данных, так как у меня есть другие объекты в этом проекте, у которых нет внешних зависимостей, которые работают совершенно нормально с управлением NHibernate.любые проблемы с кодированием, которые я мог вызвать при создании хранилища.

Любая помощь с благодарностью.Спасибо.

Ответы [ 3 ]

3 голосов
/ 14 июня 2010

Основной проблемой здесь является распространенное неправильное понимание отношения «один к одному» в реляционной базе данных и отображения HasOne в Fluent.Термины в отображении являются реляционными терминами.(Свободно пытается немного «украсить» их, что ухудшает ИМО. HasOne фактически означает: один к одному.)

Взгляните на Свободно вики :

HasOne обычно резервируется для особого случая.Как правило, в большинстве ситуаций вы бы использовали отношение References (см .: я думаю, что вы имеете в виду «многие к одному»).

Решение очень простое, просто замените HasOne на References (one-to-one до many-to-one в файле отображения XML).Вы получаете внешний ключ в базе данных, который ссылается на ProjectCatagory.


Реальное отношение один к одному в реляционной базе данных идеально отображается с помощью синхронизации первичного ключа.Когда два объекта совместно используют один и тот же первичный ключ, вы не тратите пространство на дополнительные внешние ключи, и он гарантированно равен один к одному.

Для синхронизации первичного ключа вам необходимо подключить свой ключ.другим.Однако это работает, это не то, что вам нужно здесь.

0 голосов
/ 06 декабря 2013

Кажется, класс ProjectCatagory является родительским классом Project Class.Поэтому без родительского класса, как может существовать дочерний класс.

Вы должны использовать -

Ссылки (x => x.Catagory) .Column ("Catagory_id"). Foreignkey ("Id");

здесь Foreign Key - это идентификатор вашей таблицы ProjectCatagory.

0 голосов
/ 16 июня 2010

После игры со всеми доступными опциями для картирования.Я обнаружил, что ответ похож на предложенный.

Как и предполагалось, HasOne() был явно неправильным, и References(x => x.Catagory) было частью решения.Тем не менее, я все еще получал исключения нарушения внешнего ключа до тех пор, пока:

References(x => x.Catagory).Column("Catagory_id").Cascade.SaveUpdate().Not.Nullable().Not.LazyLoad();

Просто подумал, что id обновит поток на тот случай, если кто-то еще наткнется на это с такой же проблемой, так как просто использование References() не работает.

...