powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Foreign Key Update Problem (NHibernate)
12 сообщений из 12, страница 1 из 1
Foreign Key Update Problem (NHibernate)
    #37797745
besserebrenik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго времени суток!
Возникла проблема при обновлении внешнего ключа сущности

Код: sql
1.
could not insert collection: [NHibernateForeignKeyTest.Entities.Publisher.Books#5][SQL: UPDATE [Book] SET Publisher_id = @p0, Index = @p1 WHERE BookID = @p2]



Проблема именно с Publisher_Id, его у меня нет в таблице

Диаграмма базы данных


Сущности

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
 public class Publisher
    {
        public Publisher()
        {
            _books = new List<Book>();
        }

        public virtual int Id { get; protected set; }
        public virtual string Name { get; set; }
        public virtual string Country { get; set; }
        private IList<Book> _books;
        public virtual IList<Book> Books
        {
            get { return _books; }
            set { _books = value; }
        }
    }

public class Book 
    {
        public Book()
        {
        }

        public virtual int Id { get; protected set; }
        public virtual Publisher Publisher { get; set; }
        public virtual string Title { get; set; }
        public virtual int PageCount { get; set; }
    }



Мэппинги

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
  public class BookMap : ClassMap<Book> 
    {
        public BookMap()
        {
            Id(x => x.Id, "BookID");
            Map(x => x.PageCount);
            Map(x => x.Title)
                .CustomSqlType("varchar")
                .Length(50);
            References(x => x.Publisher)
                .Column("PublisherID"); 

        }
    }

    public class PublisherMap : ClassMap<Publisher>
    {
        public PublisherMap()
        {
            Id(x => x.Id, "PublisherID");
            Map(x => x.Name)
                .CustomSqlType("varchar")
                .Length(50);
            Map(x => x.Country)
                .CustomSqlType("varchar")
                .Length(50);
            HasMany(x => x.Books)
                .AsList()
              //  .Inverse()
                .Cascade
                .All();
        }
    }



Небольшой тест
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
class Program
    {
        static void Main(string[] args)
        {
            HibernatingRhinos.Profiler.Appender.NHibernate.NHibernateProfiler.Initialize();
            var sessionManager = new SessionManager();
            using (var session = sessionManager.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    var publisher = new Publisher() {Country = "Россия", Name = "Изд"};
                    var book = new Book {PageCount = 123, Title = "Буритино", Publisher = publisher};
                    publisher.Books.Add(book);
                    session.Save(publisher); 
                    transaction.Commit();
                }
            }
        }
    }



NHProfiler показывает следующее (добавляет издателя (publisher), добавляет книгу и затем пытаеться обновить publisher_id у книги


Собственно, вопрос, почему Nhibernate генерирует в качестве FK Publisher_id, когда в мэппинге явно указан PublisherID ?


==========================
Данный частный случай - описан здесь . И проблема решается после добавления Inverse в мэппинг коллекции.

Но все же остается вопрос появления Publisher_id , как можно этого избежать?
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37797766
besserebrenik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эмм, не видел перед своим носом.
После добавления .KeyColumn("PublisherID"), эта ошибка исчезла, но теперь проблема с Index = 0 , который виден в изображении выше.
Новый мэппинг
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
   public PublisherMap()
        {
            Id(x => x.Id, "PublisherID");
            Map(x => x.Name)
                .CustomSqlType("varchar")
                .Length(50);
            Map(x => x.Country)
                .CustomSqlType("varchar")
                .Length(50);
            HasMany(x => x.Books)
                .KeyColumn("PublisherID")
                .AsList()
              //  .Inverse()
                .Cascade
                .All();
        }



"Неправильный синтаксис около \"Index\". Если имелась в виду часть табличной подсказки, то для этого теперь необходимо использовать ключевое слово A WITH и круглые скобки. Правильный синтаксис см. в электронной документации по SQL Server."
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37797798
besserebrenik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разобрался индексация появляется из-за добавления AsList()
Посоветуйте пожалуйста хороший док по NHibernate, натыкался как-то в сети, но или не сохранил закладку, либо сохранил, но не в ту папку.
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37797808
besserebrenik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И извиняюсь за офтопп.. как вы решаете проблему с тестированием ?
К примеру, пока вы не замепите весь граф, то Nhibernate будет "ругаться". Можно не мэппить весь граф, но при условии, что тестируемая сущность отображается на таблицу, в которой FK возможны Null
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37797913
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. List для nhibernate не просто коллекция, а именно нумерованный список. Т.е именно для этого он сохраняет индекс, чтобы восстановить порядок следования элементов. По-умолчанию это поле называется Index, поэтому NHibernate его и пытается вставить.
2. Неправильный синтаксис около Index - тут есть подводные камни, что такое слово - ключевое для sql, чтобы не возникала ошибка - надо его брать в ковычки. .KeyColumn("`PublisherID`"), либо в конфигурации устнавливать keyword autoimport.
3. Официальный сайт NHibernate . Там же есть документация, называется Reference .
4. Проблему с тестирования я решаю так и так .
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37799274
besserebrenik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor, спасибо за помошь!

Немного дополню - может кому интересно будет, когда набредут на эту ветку с моей проблемой именования внешних ключей.
Эту проблему можно решить двумя способами:
1) В каждом ClassMap указывать имя ключа, например
Код: c#
1.
2.
3.
.KeyColumn("`PublisherID`") // для References 
.ParenKeyColum("`PublisherID`") // для Many-to-Many
.ChildKeyColum("`PublisherID`") // для Many-to-Many



2) Использовать конвенции, подробно здесь
Пример конвенции
Код: c#
1.
2.
3.
4.
5.
6.
7.
public class ReferenceConvention : IReferenceConvention
    {
        public void Apply(IManyToOneInstance instance)
        {
            instance.Column(instance.Property.PropertyType.Name + "ID");
        }
    }



А так добавить конвенцию в вам мэппинг (фрагмент)
Код: c#
1.
2.
3.
4.
.Mappings(m => m.FluentMappings
                        .Conventions.AddFromAssemblyOf<ReferenceConvention>()
                        // или, если добавить нужно только одну Conventions.Add<ReferenceConvention>())
                    .BuildConfiguration(); 
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37799291
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
besserebrenik,

не за что. Но лучше бросьте FNH, и переходите на встроенный в NH Mapping By Code.
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37799568
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а еще лучше все сразу :)
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37799747
besserebrenik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ViPRos,

Бросить? :)


У меня вопрос еще один появился, не знаю, стоит ли заводить новый топик. Может и стоит, вопрос достаточно распространенный

Собственно, при вызове SaveOrUpdate ничего не происходит.

К примеру, вот код

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
       var sessionManager = new SessionManager();
            using (var session = sessionManager.OpenSession())
            {
                //using (var transaction = session.BeginTransaction())
                {
                    try
                    {
                        var publisher = session.Get<Publisher>(18);
                        if (publisher != null)
                        {
                            publisher.Name = "forever";
                            session.SaveOrUpdate(publisher);
                            // session.Flush(); 
                        }
                        //  transaction.Commit();
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                    Console.ReadLine();
                }
            }



Обновления происходят только в том случае, если раскомментировать flush или Commit(). Судя по этому материалу это вполне может быть нормальное поведение, т.к. объект Publisher принадлежит текущей сессии, и изменение будут сделаны только после flush.


По сути Save или SaveOrUpdate что-то наподобие ISet.Attach в EF ?
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37799750
besserebrenik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот этому материалу (чуть повыше)
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37799758
besserebrenik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Небольшое дополнение, понятно что обновления лучше делать в рамках транзакции, ведь чаще мы обновляем не одну сущность, а корень агрегации и нельзя допустить чтобы часть модели обновилось/добавилась, а другая нет.
Но все же хотелось бы понять этот вопрос
...
Рейтинг: 0 / 0
Foreign Key Update Problem (NHibernate)
    #37799918
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
besserebrenik,

будет или нет NH писать в базу при вызове методов зависит от:
1. id-generator'а сущности. native, sequence и прочие генерируемые БД заставляют NH выполнить вставку сразу.
2. FlushMode сессии. По-умолчанию OnTransactionCommit (именно поэтому сессия писала при коммите).
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Foreign Key Update Problem (NHibernate)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]