powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Жутко тормозит Fluent NHibernate
16 сообщений из 16, страница 1 из 1
Жутко тормозит Fluent NHibernate
    #36931009
stuffhappens
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Согласно профайлеру FluentConfiguration.BuildConfiguration выполняется 24 секунды. Код, конфигурирующий mapping и connection к БД:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
            MsSqlConfiguration persistenceConfigurer = MsSqlConfiguration
                         .MsSql2005
                         .ConnectionString(connectionStringBuilder => connectionStringBuilder
                                                                        .Server(server)
                                                                        .Database(database)
                                                                        .Username(userName)
                                                                        .Password(password))
                         .ProxyFactoryFactory<ProxyFactoryFactory>()
                         .CurrentSessionContext<ThreadStaticSessionContext>()
                         .DoNot.ShowSql();

            FluentConfiguration cfg = Fluently.Configure()
                    .Database(persistenceConfigurer)
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<ExecutorMap>());

            return cfg.BuildConfiguration();
. Количество map-файлов - 19.
Такая длительность построение конфигураций - это нормально??? Возможно ли, что построение конфигурации происходит так долго из-за того, что я где-нибудь криво задал маппинг? На что стоит обратить внимание, для увеличение произовдительности?
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36931159
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то мне подсказывает, что тормозит не только FluentNhibernate, а еще сам NHibernate в процессе создания SessionFactory. Разбор хмl и последующая генерация проксей - дорогое удовольствие.
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36931238
stuffhappens
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SolYUtor,

Последующие тормоза тоже наблюдаются, но в данный момент меня больше волнует FluentConfiguration.BuildConfiguration. И главный вопрос: такое время - это мой косяк, или типичное поведение данного инструмента? Насколько я понимаю NHibernate (и Fluent NHibernate) пользуются очень многие во всевозможных проектах, видимо есть какой-то магический способ заставить это работать с приемлемой скоростью. Вот я и пытаюсь понять как.
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36931753
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почитал исходники Fluent'а. Как и предполагалось, он сначала долго и мучительно генерирует xml, чтобы потом их прочитал NHibernate. А это всё не быстрые операции с текстом + рефлексия. Это Меееедленно, из принципа.
В общем, пишите xml вместо флюент-маппингов, и будет вам быстрее. Или смиритесь со своим временем. Волшебной кнопки "Сделать всё быстро" нет.
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36931868
stuffhappens
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SolYUtor,

Как-то все печально получается. Насколько я понимаю FluentNHibernate вначале генерирует все xml-ники, а NHibernate строит маппинги тоже все разом. Нельзя ли как-нибудь этим товарищам сказать, что нужно не все сразу, а по мере необходимости? Глядишь и быстрее будет...
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36932011
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stuffhappens
Нельзя ли как-нибудь этим товарищам сказать, что нужно не все сразу, а по мере необходимости?
Можно. Тут разработчики NHibernate, тут разработчики FluentNhibernate.
Напишите им свои соображения по этому поводу.

stuffhappensГлядишь и быстрее будет...

Сомневаюсь.
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36932770
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Раскинув мозгами на свежую голову, кое-что предпринять можно.
Курим тут , и тут .
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36933207
stuffhappens
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SolYUtor,

Огромное спасибо. Буду разбираться. А Вы сами пользуетесь ORM? Какой?
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36933441
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stuffhappens,

NHibernate пользую, и пока весьма им доволен. Правда, маппинги пишу вручную xml'ем.
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36933450
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SolYUtorПравда, маппинги пишу вручную xml'ем.
+1
надёжнее и красивее
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36933658
stuffhappens
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SolYUtor,

А как относитесь ко всяким LINQ-провайдорам? Или Cirteria/HQL надежнее и красивее?
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36933782
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stuffhappensА как относитесь ко всяким LINQ-провайдорам?
Сырые и маломощные. В топку.

stuffhappensИли Cirteria/HQL надежнее и красивее?
Истину глаголите.
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36934341
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stuffhappens,

Если имеется ввиду LINQ to NHibernate - то ничего против имею. Даже некоторые плюсы будут, вроде Intellisense от студии. Но сам не использую, поэтому о степени сырости ничего сказать не могу. В общем, попробуйте - потом сами для себя решите.
ICreateria не люблю - сложно воспринимать. На мой вкус HQL наиболее читабелен.

PS. FluentNHibernate использую для сохраняемости.
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36936351
stuffhappens
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пользуясь случаем, задам вопрос по NHibernate.

Есть 2 таблички: tSources(ID, Name) и tComments(ID, SourceID, Comment, Date) (Связь один-ко-многим).
Требуется по каждому источнику вевести его название и последний (по дате) к нему комменарий.
Классы, описывающие сущности:
Код: plaintext
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.
    public class Source
    {
        public virtual int ID { get; set; }
        public virtual string Name { get; set; }

        public virtual IList<Comment> Comments { get; private set; }

        public virtual string LastComment
        {
            get
            {
                if (!Comments.Any())
                    return null;

                return Comments.OrderByDescending(x => x.Date).First().Comment;
            }
        }


        public Source()
        {
            Comments = new List<Comment>();
        }
    }

    public class Comment
    {
        public virtual int ID { get; set; }
        public virtual DateTime Date { get; set; }
        public virtual string Comment { get; set; }
        public virtual Source Source { get; set; }

    }


Классы, задающие маппинг на FluentNH:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
    public class SourceMap : ClassMap<Source>
    {
        public SourceMap()
        {
            Table("dbo.tSource");

            Id(x => x.ID);
            Map(x => x.Name).Column("SourceName");
            HasMany(x => x.Comments).Inverse().Cascade.All();
        }
    }

    public class CommentMap : ClassMap<Comment>
    {
        public CommentMap()
        {
            Id(x => x.ID);
            Map(x => x.Date);
            Map(x => x.Comment);
            References(x => x.Source).Column("SourceID");
        }
    }

.

Ну и для получения нужного результата я получаю все источники и для каждого из них вызываю LastComment. В итого время работы нереально велико. Если посмотреть на SQL-запросы, генерируемые NHibernate, то видно, что для каждого ID источника выполняется запрос типа
Код: plaintext
1.
2.
SELECT * FROM tComments
WHERE SourceID = @p;
@p = n. 
То есть таких запросов выполняется очень много (столько, сколько источников). Почему NHibernate не хочет сделать 1 запрос типа:
Код: plaintext
1.
2.
SELECT s.*, c.* FROM
tSources s LEFT JOIN tComments c
ON s.ID = c.SourceID
?
Может быть его можно заставить это сделать? Как?
Заранее спасибо!
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36936724
SolYUtor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. В маппинге Source схему для таблицы указывайте методом Schema, а не Table
2. Классы у вас слишком много позволяют делать со своим состоянием извне. Жестчё инкапсулировать надо.
3. В NHibernate именно вы управляете стратегией извлечения данных. По умолчанию всё грузиться в ленивом режиме, поэтому и получаются такие запросы. Заставить грузить через Left join просто:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    public class SourceMap : ClassMap<Source>
    {
        public SourceMap()
        {
            Table("Source");
            

            Id(x => x.ID);
            Map(x => x.Name).Column("SourceName");
            HasMany(x => x.Comments).Inverse().Cascade.All().Fetch.Join(); //Fetch.Join()!!
        }
    }
Дополнительно можно поиграться с параметром BatchSize

4. Имхо, если нужен только последний комментарий, то грузить все остальные - это как-то не жирно. Они все будут складываться в кеш первого уровня, отслеживать состояние и т.д.

Я бы сделал так:
Код: plaintext
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.
    public class Source
    {
        public virtual int ID { get; set; }
        public virtual string Name { get; set; }

        private IList<Comment> _comments;
        public virtual IList<Comment> Comments
        {
            get { return new List<Comment>(_comments).AsReadOnly(); }
            private set { _comments = value; }
        }

        public virtual Comment LastComment {get; private set;}

        public Source()
        {
            Comments = new List<Comment>();
        }

        public virtual void AddComment(Comment comment)
        {
            LastComment = comment;
            comment.Source = this;
            _comments.Add(comment);
        }
    }

    public class Comment
    {
        public virtual int ID { get; set; }
        public virtual DateTime Date { get; set; }
        public virtual string Comments { get; set; }
        public virtual Source Source { get; set; }

    }

    public class SourceMap : ClassMap<Source>
    {
        public SourceMap()
        {
            Table("Source");
            

            Id(x => x.ID);
            Map(x => x.Name).Column("SourceName");
            HasMany(x => x.Comments).Access.CamelCaseField(Prefix.Underscore).Inverse().Cascade.All();
            References(source => source.LastComment).Fetch.Join();
        }
    }

    public class CommentMap : ClassMap<Comment>
    {
        public CommentMap()
        {
            Id(x => x.ID);
            Map(x => x.Date);
            Map(x => x.Comments);
            References(x => x.Source).Column("SourceID");
        }
    }

    [TestFixture]
    public class EagerFetchingFixture
    {
        #region Setup/Teardown

        [SetUp]
        public void SetUp()
        {

            var persister = SQLiteConfiguration
                .Standard
                .UsingFile("Test.db")
                .ShowSql();


             _config = Fluently
                 .Configure()
                 .Database(persister)
                 .Mappings(map => map.FluentMappings.AddFromAssemblyOf<Source>())
                .BuildConfiguration();

             _sessionFactory = _config.BuildSessionFactory();

             new SchemaExport(_config).Execute(true, true, false);
        }

        #endregion

        private ISessionFactory _sessionFactory;
        private Configuration _config;

        [Test]
        public void Test()
        {
            using(var session = _sessionFactory.OpenSession())
            {
                var source = new Source {Name = Guid.NewGuid().ToString()};

                source.AddComment(new Comment {Comments = Guid.NewGuid().ToString(), Date = DateTime.Now});
                source.AddComment(new Comment { Comments = Guid.NewGuid().ToString(), Date = DateTime.Now});
                source.AddComment(new Comment { Comments = Guid.NewGuid().ToString(), Date = DateTime.Now});

                session.Persist(source);
                session.Flush();
                session.Clear();

                var s2 = session.Get<Source>(1);

                var comment = s2.LastComment.Comments;
                
            }
        }

Результат:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
drop table if exists "Comment"

    drop table if exists Source

    create table "Comment" (
        ID  integer,
       Date DATETIME,
       Comments TEXT,
       SourceID INTEGER,
       primary key (ID)
    )

    create table Source (
        ID  integer,
       SourceName TEXT,
       LastComment_id INTEGER,
       primary key (ID)
    )
NHibernate: INSERT INTO Source (SourceName, LastComment_id) VALUES (@p0, @p1); select last_insert_rowid();@p0 = 'cfe8d711-876c-4bca-96f1-f2f410d8fdea', @p1 = NULL
NHibernate: INSERT INTO "Comment" (Date, Comments, SourceID) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 03.11.2010 16:07:20, @p1 = '44c7b1fc-8bae-4cb3-a4ac-5dcdbb02884a', @p2 = 1
NHibernate: INSERT INTO "Comment" (Date, Comments, SourceID) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 03.11.2010 16:07:20, @p1 = '01156992-8cab-4100-8311-0e9e29e9c659', @p2 = 1
NHibernate: INSERT INTO "Comment" (Date, Comments, SourceID) VALUES (@p0, @p1, @p2); select last_insert_rowid();@p0 = 03.11.2010 16:07:20, @p1 = 'af72a15a-0aa5-4ca5-ab97-40b8e0e53d86', @p2 = 1
NHibernate: UPDATE Source SET SourceName = @p0, LastComment_id = @p1 WHERE ID = @p2;@p0 = 'cfe8d711-876c-4bca-96f1-f2f410d8fdea', @p1 = 3, @p2 = 1
NHibernate: SELECT source0_.ID as ID1_1_, source0_.SourceName as SourceName1_1_, source0_.LastComment_id as LastComm3_1_1_, comment1_.ID as ID0_0_, comment1_.Date as Date0_0_, comment1_.Comments as Comments0_0_, comment1_.SourceID as SourceID0_0_ FROM Source source0_ left outer join "Comment" comment1_ on source0_.LastComment_id=comment1_.ID WHERE source0_.ID=@p0;@p0 = 1


5. Рекомендую осилить NHibernate in Action.
...
Рейтинг: 0 / 0
Жутко тормозит Fluent NHibernate
    #36941685
stuffhappens
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SolYUtor,

Спсибо за ответ!
Изучал NHibernate по вот этим скринкастам , но качеством материала остался недоволен. Видимо, действительно нужно читать NHibernate in action.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Жутко тормозит Fluent NHibernate
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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