powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / NHibernate не мапятся товары с категориями
22 сообщений из 22, страница 1 из 1
NHibernate не мапятся товары с категориями
    #38017794
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вроде бы ничего сложного, но почему-то не выходит. Есть пара сущностей:

Category
Код: 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.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
using System;
using System.Collections.Generic;
using System.Linq;

namespace Shop.Domain
{
    /// <summary>
    /// Категория товара.
    /// </summary>
    public class Category : Entity
    {
        private IList<Category> childCategories = new List<Category>();
        private IList<Product> products = new List<Product>();
        private Category parentCategory;

        /// <summary>
        /// Наименование.
        /// </summary>
        public virtual string Name { get; set; }

        /// <summary>
        /// Родительская категория.
        /// </summary>
        /// <exception cref="ArgumentNullException">Параметр <paramref name="value"/> равен null.</exception>
        public virtual Category ParentCategory
        {
            get
            {
                return this.parentCategory;
            }

            set
            {
                if (value == null) throw new ArgumentNullException();

                if (this.parentCategory == value) return;

                var childCategories = this.GetChildCategories(this, true);
                if (childCategories.Contains(value))// Новым родителем назначается одна из нижележащих категорий.
                {
                    // У текущего родителя нового родителя удалить из списка дочерних нового родителя.
                    value.parentCategory.childCategories.Remove(value);
                    // Назначить новому родителю родителем родителя текущей категории.
                    value.parentCategory = this.parentCategory;
                    // Родителю текущей категории в дочерние добавить нового родителя.
                    if (this.parentCategory != null)// Возможно текущая категория это корневая категория.
                        this.parentCategory.childCategories.Add(value);
                }

                // У текущего родителя текущей категории удалить из списка дочерних текущую категорию.
                if (this.parentCategory != null)// Возможно текущая категория это корневая или новая категория.
                    //Удалим себя из дочерних категорий текущей родительской категории.
                    this.parentCategory.childCategories.Remove(this);
                // Назначить нового родителя.
                this.parentCategory = value;
                // Добавить текущую категорию в список дочерних категорий новой родительской категории.
                value.childCategories.Add(this);
            }
        }

        /// <summary>
        /// Дочерние категории.
        /// </summary>
        public virtual IEnumerable<Category> ChildCategories { get { return this.childCategories; } }

        /// <summary>
        /// Товары.
        /// </summary>
        public virtual IEnumerable<Product> Products { get { return this.products; } }

        /// <summary>
        /// Добавляет дочернюю категорию.
        /// </summary>
        /// <param name="category">Категория/</param>
        /// <exception cref="ArgumentNullException">Параметр <paramref name="category"/> равен null.</exception>
        /// <exception cref="ArgumentException">Параметр <paramref name="category"/> равен this.</exception>
        public virtual void AddChildCategory(Category category)
        {
            if (category == null) throw new ArgumentNullException("category");

            if (this.childCategories.Contains(category)) return;

            if (category == this) throw new ArgumentException("Нельзя добавлять себя в свои дочерние категории.");

            var parentCategories = this.GetParentCategories(this);
            if (parentCategories.Contains(category))// Указанная категория является вышестоящей.
            {// Нельзя образовывать кольцевые связи, когда к дочерней категории можно добраться по цепочке родителей.
                //Кроме того такое кольцо будет оторвано от основного дерева и не будет иметь корня.
                // У родителя текущей категории удалить из дочерних текущую.
                this.parentCategory.childCategories.Remove(this);
                // Родителем текущей категории сделать родителя добавляемой.
                this.parentCategory = category.parentCategory;
                // Новому родителю текущей категории добавить в дочерние текущую категорию.
                if (this.parentCategory != null)// Возможно текущая категория стала корневой.
                    this.parentCategory.childCategories.Add(this);
            }

            // У родителя добавляемой категории удалить добавляемую из дочерних категорий.
            if (category.parentCategory != null)// Возможно это корневая или новая категория.
                category.parentCategory.childCategories.Remove(category);
            // Добавляемой категории установить в качестве родителя текущую категорию.
            category.parentCategory = this;
            // Текущей категории добавить в дочерние добавляемую категорию.
            this.childCategories.Add(category);
        }

        /// <summary>
        /// Удаляет дочернюю категорию.
        /// </summary>
        /// <param name="category">Категория.</param>
        /// <exception cref="ArgumentNullException">Параметр <paramref name="category"/> равен null.</exception>
        public virtual void RemoveChildCategory(Category category)
        {
            if (category == null) throw new ArgumentNullException("category");

            var c = this.childCategories.SingleOrDefault(x => x == category);
            if (c != null)
            {
                c.parentCategory = null;
                this.childCategories.Remove(c);
            }
        }

        /// <summary>
        /// Добавляет товар.
        /// </summary>
        /// <param name="product">Товар.</param>
        /// <exception cref="ArgumentNullException">Параметр <paramref name="product"/> равен null.</exception>
        public virtual void AddProduct(Product product)
        {
            if (product == null) throw new ArgumentNullException("product");

            if (!this.products.Contains(product))
            {
                this.products.Add(product);
                product.AddCategory(this);
            }
        }

        /// <summary>
        /// Удаляет товар.
        /// </summary>
        /// <param name="product">Товар.</param>
        /// <exception cref="ArgumentNullException">Параметр <paramref name="product"/> равен null.</exception>
        public virtual void RemoveProduct(Product product)
        {
            if (product == null) throw new ArgumentNullException("product");

            if (this.products.Contains(product))
            {
                this.products.Remove(product);
                product.RemoveCategory(this);
            }
        }

        /// <summary>
        /// Возвращает дочерние категорий указанной категории в виде перечислителя.
        /// </summary>
        /// <param name="parent">Категория, перечислитель дочерних которой требуется получить.</param>
        /// <param name="includingChild">Значение, указывающее, необходимо ли включать в выборку
        /// категории из дочерних категорий указанной категории.</param>
        /// <returns>Перечислитель дочерних категорий.</returns>
        private IEnumerable<Category> GetChildCategories(Category parent, bool includingChild = false)
        {
            if (includingChild)
            {
                var childCategories = parent.childCategories.SelectMany(x => parent.GetChildCategories(x, true));
                return parent.childCategories.Union(childCategories);
            }
            else
                return parent.childCategories;
        }

        /// <summary>
        /// Возвращает перечислитель всех вышестоящих категорий.
        /// </summary>
        /// <param name="category">Категория, для которой нужно получить вышестоящие категории.</param>
        /// <returns>Перечислитель вышестоящих категорий.</returns>
        private IEnumerable<Category> GetParentCategories(Category category)
        {
            var list = new List<Category>();

            if (category.parentCategory != null)
            {
                list.Add(category.parentCategory);
                return list.Union(category.parentCategory.GetParentCategories(category.parentCategory));
            }

            return list;
        }
    }
}



Product
Код: 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.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Shop.Domain
{
    /// <summary>
    /// Товар.
    /// </summary>
    public class Product : Entity
    {
        private IList<Category> categories = new List<Category>();

        /// <summary>
        /// Наименование.
        /// </summary>
        public virtual string Name { get; set; }

        /// <summary>
        /// Цена.
        /// </summary>
        public virtual decimal Price { get; set; }

        /// <summary>
        /// Наличие скидки.
        /// </summary>
        public virtual bool Discounted { get; set; }

        /// <summary>
        /// Размер скидки в процентах.
        /// </summary>
        public virtual decimal Discount { get; set; }

        /// <summary>
        /// Категории, к которым относится товар.
        /// </summary>
        public virtual IEnumerable<Category> Categories { get { return this.categories; } }

        /// <summary>
        /// Добавляет категорию.
        /// </summary>
        /// <param name="category">Категория/</param>
        /// <exception cref="ArgumentNullException">Параметр <paramref name="category"/> равен null.</exception>
        public virtual void AddCategory(Category category)
        {
            if (category == null) throw new ArgumentNullException("category");

            if (!this.categories.Contains(category))
            {
                this.categories.Add(category);
                category.AddProduct(this);
            }
        }

        /// <summary>
        /// Удаляет категорию.
        /// </summary>
        /// <param name="category">Категория.</param>
        /// <exception cref="ArgumentNullException">Параметр <paramref name="category"/> равен null.</exception>
        public virtual void RemoveCategory(Category category)
        {
            if (category == null) throw new ArgumentNullException("category");

            if (this.categories.Contains(category))
            {
                this.categories.Remove(category);
                category.RemoveProduct(this);
            }
        }
    }
}



И их маппинги:

[spoiler Category][SRC c#]
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38017799
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И их маппинги:

Mappings
Код: 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.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
using FluentNHibernate.Mapping;
using Shop.Domain;

namespace NHInfrastructure.Mappings
{
    class CategoryMap : ClassMap<Category>
    {
        public CategoryMap()
        {
            Id(x => x.ID);
            Map(x => x.Name);
            References(x => x.ParentCategory)
                .Access.CamelCaseField()
                .Cascade.SaveUpdate();

            HasMany(x => x.ChildCategories)
                .Inverse()
                .Cascade.SaveUpdate();

            HasManyToMany(x => x.Products)
                .Inverse()
                .Cascade.SaveUpdate();
        }
    }
}

using FluentNHibernate.Mapping;
using Shop.Domain;

namespace NHInfrastructure.Mappings
{
    class ProductMap : ClassMap<Product>
    {
        public ProductMap()
        {
            Id(x => x.ID);
            Map(x => x.Name);
            Map(x => x.Price);
            Map(x => x.Discounted);
            Map(x => x.Discount);

            HasManyToMany(x => x.Categories)
                .Cascade.SaveUpdate();
        }
    }
}



Выполняем код:

Код: 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.
34.
35.
36.
37.
38.
39.
40.
using System;
using NHInfrastructure;
using Shop.Domain;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var rootCategory = new Category();
            var parentCategory1 = new Category();
            var parentCategory2 = new Category();
            var category = new Category();
            var childCategory1 = new Category();
            var childCategory2 = new Category();

            childCategory2.ParentCategory = childCategory1;
            childCategory1.ParentCategory = category;
            category.ParentCategory = parentCategory2;
            parentCategory2.ParentCategory = parentCategory1;
            parentCategory1.ParentCategory = rootCategory;

            var p1 = new Product(); p1.Name = "p1";
            var p2 = new Product(); p2.Name = "p2";

            category.AddProduct(p1);
            category.AddProduct(p2);

            var session = NHManager.GetSession();
            var catID = (int)session.Save(category);

            var newSession = NHManager.GetSession();
            var c = newSession.Load<Category>(catID);
            // А товаров в c.Products нет ни одного.
            Console.WriteLine("Stop");
            Console.ReadKey();
        }
    }
}



Структура категорий сохраняется и читается из базы нормально. Два созданных товара тоже добавляются в базу. А вот связи товаров с категориями не сохраняются. В чем дело? Думается мне что-то с маппингом неправильно, но что именно, ведь вроде все по букварям написано?
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018320
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lexxxxx,

сериализуйте маппинги, посмотрите, что получилось в виде xml.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018321
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

И убедитесь, что всё правильно в памяти. Если в памяти ошибки в связях - в базе будет тоже самое.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018356
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtorLexxxxx,

сериализуйте маппинги, посмотрите, что получилось в виде xml.

Не могли бы Вы "на пальцах" рассказать как это делается?

В памяти перед сохранением вроде все нормально. Категория содержит два продукта, оба продукта имеют по одной и той же категории. Сохранение в базу проходит без исключений, но в таблице, которая связывает продукты и категории, нет ни одной записи. Соответственно при чтении из базы получаем категорию без продуктов.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018489
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На всякий случай выкладываю проектик с сущностями. http://dump.ru/file/5890203
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018508
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018546
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

Спасибо.

Вот что получается:

Код: xml
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.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Shop.Domain.Category, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Category`">
    <id name="ID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="ID" />
      <generator class="identity" />
    </id>
    <bag access="nosetter.camelcase" cascade="save-update" inverse="true" name="ChildCategories">
      <key>
        <column name="ParentCategory_id" />
      </key>
      <one-to-many class="Shop.Domain.Category, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bag>
    <bag access="nosetter.lowercase" cascade="all" name="Products" table="CategoriesToProducts">
      <key>
        <column name="Category_id" />
      </key>
      <many-to-many class="Shop.Domain.Product, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <column name="Product_id" />
      </many-to-many>
    </bag>
    <property name="Name" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" />
    </property>
    <many-to-one access="field.camelcase" cascade="save-update" class="Shop.Domain.Category, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" name="ParentCategory">
      <column name="ParentCategory_id" />
    </many-to-one>
  </class>
</hibernate-mapping>



Код: xml
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.
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class xmlns="urn:nhibernate-mapping-2.2" name="Shop.Domain.Product, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Product`">
    <id name="ID" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="ID" />
      <generator class="identity" />
    </id>
    <bag access="nosetter.lowercase" cascade="all" inverse="true" name="Categories" table="CategoriesToProducts">
      <key>
        <column name="Product_id" />
      </key>
      <many-to-many class="Shop.Domain.Category, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <column name="Category_id" />
      </many-to-many>
    </bag>
    <property name="Name" type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Name" />
    </property>
    <property name="Price" type="System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Price" />
    </property>
    <property name="Discounted" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Discounted" />
    </property>
    <property name="Discount" type="System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <column name="Discount" />
    </property>
  </class>
</hibernate-mapping>



На мой взгляд все вроде правильно, но не работает! Какого рожна ему надобно?!
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018571
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lexxxxx,

Включите логгирование sql-запросов, и посмотрите, что он реально вставляет в бд.
Если не поможет - попробуйте убрать inverse=true.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018597
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

Вставляет он шесть категорий
Код: sql
1.
INSERT INTO [Category] (Name, ParentCategory_id) VALUES (@p0, @p1); select SCOPE_IDENTITY()


и два товара
Код: sql
1.
INSERT INTO [Product] (Name, Price, Discounted, Discount) VALUES (@p0, @p1, @p2, @p3); select SCOPE_IDENTITY()


как и было задумано.
А вот к таблице [CategoriesToProducts], которую он сгенерил чтобы связи хранить, обращений не производится.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018599
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

Удаление инверсии ничего не дает.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018632
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lexxxxx,

У вас перепутаны названия столбцов в <key> и <many-to-many>. Смотрите пример .

PS.1. Подумайте, надо ли вам bag? Мне кажется set здесь будет больше к теме.
PS.2. Bag лучше использовать только на legacy-базах. Если приложении своё и новое - используйте idbag.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018773
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

Вариант
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
<set access="nosetter.lowercase" cascade="all" name="Categories" table="CategoriesToProducts">
      <key>
        <column name="Category_id" />
      </key>
      <many-to-many class="Shop.Domain.Category, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <column name="Product_id" />
      </many-to-many>
    </set>



Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
 <set access="nosetter.lowercase" cascade="all" name="Products" table="CategoriesToProducts">
      <key>
        <column name="Product_id" />
      </key>
      <many-to-many class="Shop.Domain.Product, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
        <column name="Category_id" />
      </many-to-many>
    </set>



тоже не дал положительного результата.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38018833
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

Что интересно, пример с http://slynetblog.blogspot.com/2009/10/nhibernate.html тоже не работает.
И свойства в <key> и <many-to-many> у меня вроде перепутаны не были (хотя переворот тоже результата не дал).
Что же за фигня?! Вроде все как надо, а не фунциклирует!
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38019153
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Решение проблемы найдено. Оно оказалось совсем не очевидным, на мой взгляд.
Сущности и маппинги оказались в порядке. Оказалось все происходит из-за того что сохранение сущности не обернуто в транзакцию. Решение нашел случайно в комментах к одной статье.
Честно говоря это для меня дикость, что связь между сущностями (по сути один оператор SQL) не посылается в базу потому что все сохранение не обернуто транзакцией! Это наверное поэтому в букваре по NHibernate рекомендуют все оборачивать в транзакции, потому что сами толком не знают как оно работать будет и чего от него ожидать?!
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38019168
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lexxxxx,

NHibernate предпринимает очень много действий, чтобы добиться высокой производительности. Одно из них - как можно дольше откладывать обращение к БД, и записывать данные пачкой. В вашем случае для сущностей Продукт и Категория хибер был вынужден лезть в базу, чтобы получить значение identity. А вот для таблицы связи это было необязательно, т.к. Id он уже знал.
Если бы вы использовали Hilo генератор ( что я и рекомендую ) nhibernate не стал бы генерировать запрос на вставку даже для Продукта и Категорий.
Если очень хочется работать без транзакций вызывайте Flush, или ставьте у сессии SessionMode = AutoFlush.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38019199
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

Спасибо за науку! Мои познания в NHibernate крайне слабы и для меня будет очень полезной указанная Вами статья.
Что-то я не нахожу у ISession свойства SessionMode. Может речь идет о session.FlushMode = NHibernate.FlushMode.Always?
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38019232
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LexxxxxSolYUtor,
Что-то я не нахожу у ISession свойства SessionMode. Может речь идет о session.FlushMode = NHibernate.FlushMode.Always?
Угу, именно оно. Описался.

А вообще говоря, NHibernate построен с unit of work в голове. Реализацией uow и является сессия. И правильно работать с ней примерно так: создали сессию, открыли транзакцию, сделали какой-то логический кусок работы, закрыли транзакцию, закрыли сессию.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38019266
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

В Вашей статье написано "nhibernate высчитывает диапазон по формуле high * (max_lo + 1)..high * (max_lo + 1) + max_lo." Но не ясно (или я не внимательно читал) где и кем задается число high? Число max_lo, как я понял, пользователь задает сам при маппинге сущности. Хотелось бы детально понять как работает hilo генератор чтобы точно знать как правильно выбрать значение max_lo.
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38019455
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lexxxxx,

Хибер поддерживает отдельную таблицу в бд (указывается в маппинге генератора), где держит текущее значение hi. Когда полностью выбирает диапазон (или при старте приложения) он в транзакции считывает это число, и потом увеличивает его на 1. И так снова до следующего раза или исчерпания диапазона. Таким образом, можно использовать даже несколько разных экземпляров хибера, т.к. они никогда не смогут получить одинаковое число hi.
hilo-генератор можно настроить в двух вариантах:
1. Глобальные id на все сущности в базе (в последнее время склоняюсь к этому варианту, т.к. он требует меньше усилий).
2. Уникальные id в пределах иерархии классов. Для этого надо прописывать условие where в генераторе, и заполнять ту самую таблицу указанными значениями.

Я обычно использую max_lo = 49. Тогда диапазон получается 50
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38019712
Lexxxxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtor,

Не могу понять как заставить использовать глобальное пространство идентификаторов для всех сущностей.
Как я понял, если я указываю в маппинге сущности
Код: c#
1.
Id(x => x.ID).GeneratedBy.HiLo("100");


то для нее будет выделен диапазон в сто идентификаторов. Для остальных сущностей нужно тоже явно включать использование HiLo и указывать свой max_lo . А как заставить NH использовать HiLo для всех сущностей сразу и указать один max_lo для всех сущностей?
...
Рейтинг: 0 / 0
NHibernate не мапятся товары с категориями
    #38020782
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lexxxxx,

в class by class маппинге только писать для каждого класса Id(x => x.ID).GeneratedBy.HiLo("100"), либо использовать маппинг по соглашениям.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / NHibernate не мапятся товары с категориями
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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