Свободный NHibernate один-ко-многим отключает ограничение внешнего ключа

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

NHibernate.Exceptions.GenericADOException: не удалось выполнить запрос на обновление [SQL: удалить из [Customer]] ---> System.Data.SqlClient.SqlException: оператор DELETE вступил в конфликт с ограничением REFERENCE "FK7867CB245055157F"

У меня есть аналогичное взаимно-однозначное отношение, когда я должен иметь возможность удалить объект на одном конце без внешнего ключа на другом конце, который должен быть установлен в NULL, и я успешно решил эту проблему, используя NotFound.Ignore () . Я нашел несколько ответов, предлагающих именно это решение, но, похоже, оно вообще не имеет никакого эффекта. Я использую свое отображение для создания базы данных BTW.

Вот мои сущности и сопоставления:

public class User : Entity
{
    ...
    public virtual Customer Customer { get; set; }
    ...
}
public class Customer : Entity
{
    ...
    public virtual string CustomerNumber { get; set; }
    public virtual User User { get; set; }
    public virtual IList<Vehicle> Vehicles { get; set; }
    ...
}
public class Vehicle : Entity
{
    ...
    public virtual string SerialNumber { get; set; }
    public virtual Customer Customer { get; set; }
    ...
}

Я использую AutoMapping и переопределяю:

public class UserMappingOverride : IAutoMappingOverride<User>
{
    public void Override(AutoMapping<User> mapping)
    {
        ...
        mapping.References(u => u.Customer).Column("CustomerNumber").NotFound.Ignore();
    }
}
public class CustomerMappingOverride : IAutoMappingOverride<Customer>
{
    public void Override(AutoMapping<Customer> mapping)
    {
        mapping.Id(u => u.Kundenummer).GeneratedBy.Assigned().Not.Nullable();
        mapping.HasOne(u => u.User).PropertyRef(c => c.Customer);
        mapping.HasMany(u => u.Vehicles).KeyColumns.Add("CustomerNumber")
            .Cascade.None()
            .Inverse();
    }
}
public class VehicleMappingOverride : IAutoMappingOverride<Vehicle>
{
    public void Override(AutoMapping<Vehicle> mapping)
    {
        mapping.Id(u => u.SerialNumber).GeneratedBy.Assigned().Not.Nullable();
        mapping.References(u => u.Customer).Column("CustomerNumber").NotFound.Ignore();
    }
}

Как уже говорилось, во взаимно-однозначном отношении при сопоставлении User я использую NotFound.Ignore (), который выполняет обещанное - позволяет мне удалить клиента, не вызывая исключения нарушения ограничения, и по-прежнему сохранять значения «CustomerNumber» "в таблице User нетронутой. Отображение взаимосвязи между сущностями пользователя и клиента просто не создает ограничения внешнего ключа в базе данных, когда база данных строится из сопоставления.

Но то же самое не работает с моими отношениями «один ко многим». Хотя сопоставление почти такое же, как и мои отношения один-к-одному, и я использую NotFound.Ignore (), как предлагается в аналогичных вопросах здесь, это отношение по-прежнему создает ограничение внешнего ключа, и я получаю исключение нарушения ограничения при попытке удалить клиент. Единственный обходной путь - вручную удалить FK в базе данных или изменить его, установив для параметра Enforce Foreign Key Constraint значение False.

Как я могу заставить NHibernate либо не создавать это ограничение внешнего ключа, либо устанавливать для ограничения внешнего ключа Enfore значение False при построении базы данных?

С наилучшими пожеланиями - Николай

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


person Nikolaj Dam Larsen    schedule 16.10.2012    source источник


Ответы (2)


нельзя обойти ФК в базе. Я предполагаю, что нет FK от пользователя к клиенту. Если вы создаете схему из сопоставлений, вам необходимо отключить создание FK с помощью mapping.References(u => u.Customer).ForeignKey("none");

person Firo    schedule 18.10.2012
comment
Ваша догадка верна. Я попытался объяснить, что это было текущее поведение, но, возможно, я не был достаточно ясным: Отображение отношений между сущностями пользователя и клиента просто не создает ограничение внешнего ключа в базе данных, когда база данных построен на основе сопоставления. Ваш ответ указал в правильном направлении, я знал, что мне нужно избавиться от FK, просто не знал, как заставить NHibernate сделать это за меня. - person Nikolaj Dam Larsen; 20.10.2012

Ответ Фиро указал мне в правильном направлении, как избавиться от ограничения FK. Однако добавление .ForeignKey("none") в сопоставление транспортных средств этого не дало. Но добавление аналогичного свойства в отображение клиентов решило мою проблему.

Итак, решение стало:

mapping.HasMany(u => u.Vehicles).ForeignKeyConstraintName("none")
person Nikolaj Dam Larsen    schedule 20.10.2012