Форум программистов, компьютерный форум, киберфорум
Наши страницы
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
DarkOrk
17 / 17 / 8
Регистрация: 06.02.2015
Сообщений: 353
1

EF, загрузка модели

14.07.2017, 02:09. Просмотров 1111. Ответов 16

Пипол, может банальный вопрос, но я чёт не въеду как исправить.

Работаем через кодфёрст (помоему с 6м еф-ом )

Есть модель, в ней есть навигационные свойства.
Я их установил с public virtual модификаторами.

Создаю контекст. Гружу данные. Вызываю метод ToArray() и сейваю в поле класса.

А тут велезло ЧП - после того как контекст задиспосился, все данные из навигационных свойств тоже задиспосились.

Вопрос - как мне сейвнуть, в месте с основной выборкой, все данные которые лежат в навигационных свойствах на момент жизни контекста, ну и что бы дальше они жили у меня в памяти?

Добавлено через 47 секунд
Ну да, ответы из серии "выключить лейзи-лоадинг" - не канают! Тогда свойства вообще не загрузятся (сами по себе), а мне вся инфа нужна!

Добавлено через 1 час 50 минут
АУсь, люди признавайтесь, как это сделать?))

Добавлено через 4 часа 31 минуту
Спс пипол.
Решение моей проблемы было найдено... - при применении метода .Include

Кстати, ну раз linq эту проблему (вложенностей) решает, то 100% и в fluent api это решение есть. Кто-то его знает? (аналог .Include ?)

Добавлено через 24 минуты
Продолжаем опрос

Нашёл ситуацию в которой это решение "не дорабатывает" - в случае если много вложеностей. То есть, если у нас модель А ссылается на множество моделей А и т.д. то .Include(x=>x.OurList_A) прогрузит только первый уровень вложеностей (ну точнее это уже 2й уровень), а все последующие нет. Как исправить?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.07.2017, 02:09
Ответы с готовыми решениями:

Загрузка 3D модели
Нужно загрузить 3D модель или средствами Open GLES 2.0 или стандартными...

Загрузка модели из файла
Подскажите у opengl в отличи от директа нет своего формата и функции загрузки...

Загрузка ASE модели
Здравствуйте, Не могу разобраться с форматом ASE, а именно что значат...

Загрузка 3D модели в браузер
Я хочу сделать проект... Щас расскажу подробности.. Например, делаешь модель...

Загрузка obj модели в OpenGl
Есть .obj файл типа: v 1.25022 0 -0.0571689 vt -49.2212 2.25074 vn 0 -1 -0...

16
IamRain
1407 / 1254 / 395
Регистрация: 02.08.2011
Сообщений: 3,723
14.07.2017, 02:22 2
Цитата Сообщение от DarkOrk Посмотреть сообщение
Как исправить?
DarkOrk, вы можете в Include включать и граф объектов, а не только одну сущность. Типа того:
C#
1
2
3
4
5
 var filter ="test";
 using(var context = new SomeContext())
  {
        var inMemory = context.Foos.Where(f => f.Name.Equals(filter)).Include("Bar.Baz").ToArray();
   }
То есть тут мы ушли глубже и захватили из БД также Baz объект объекта Bar.

Цитата Сообщение от DarkOrk Посмотреть сообщение
Кстати, ну раз linq эту проблему (вложенностей) решает, то 100% и в fluent api это решение есть. Кто-то его знает? (аналог .Include ?)
Это не LINQ, это просто расширение для IQuerable вроде, никакого отношения к LINQ не имеет. И Fluent API используется лишь для конфигурирования, а не для управления загрузкой сущностей.
0
DarkOrk
17 / 17 / 8
Регистрация: 06.02.2015
Сообщений: 353
14.07.2017, 02:51  [ТС] 3
IamRain, 1. спс за инфу. Буду знать и в предь ерунда про linq не говорить.
2. по факту моего вопроса - вы предложили вариант, а в случае если вложеностей не ограниченное кол-во? (ну точнее я не знаю кол-во вложеностей) то в этом случае как поступать?
0
IamRain
1407 / 1254 / 395
Регистрация: 02.08.2011
Сообщений: 3,723
14.07.2017, 03:05 4
Цитата Сообщение от DarkOrk Посмотреть сообщение
а в случае если вложеностей не ограниченное кол-во?
В таком случае не надо использовать Include, а используйте lazy loading, насколько я знаю, это единственное что может предложить EF, и все там будет работать после Disposing-а вашего контекста. Главное убедиться, что вы работаете не с прокси классами, а уже конечными сущностями.

Цитата Сообщение от DarkOrk Посмотреть сообщение
А тут велезло ЧП - после того как контекст задиспосился, все данные из навигационных свойств тоже задиспосились.
Значит надо доставать данные до disposing-а, или продлить время жизни контекста.
0
DarkOrk
17 / 17 / 8
Регистрация: 06.02.2015
Сообщений: 353
14.07.2017, 03:24  [ТС] 5
IamRain, да, в отладке видно, что это прокси классы.
У меня там 4 условных этапа. Скорректируйте меня пожалуйста.

1. У нас есть обьект (моделька из БД).
C#
1
2
3
4
5
6
7
8
9
    public class TestFolder
    {
        public int ID { get; set; }
        public Nullable<int> FolderID { get; set; } //id вложенного объекта
        public string Name { get; set; }
 
        public virtual TestFolder FolderParent { get; set; } //родитель...
        public virtual List<TestFolder> FolderContains { get; set; } //это наши вложенные объекты
    }
2. Настраиваем отношения
C#
1
2
3
4
5
6
7
8
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
 
            modelBuilder.Entity<Models.TestFolder>().HasKey(x => x.ID).ToTable("TestFolders");
 
            modelBuilder.Entity<Models.TestFolder>().HasOptional(x => x.FolderParent).WithMany(x => x.FolderContains).HasForeignKey(x => x.FolderID);
        }
3. Гребём данные
C#
1
2
3
4
5
6
7
8
            using (var context = new DbContext())
            {
                _testFolders = context
                    .TestFolders
                    .Include(x => x.FolderContains)
                    .Include(x=>x.FolderParent)
                    .Where(x => x.FolderID == 0).ToArray();
            }
4. Обрабатываем данные

....а при обработки, юзая поле _testFolders вложенных элементов нет
0
IamRain
1407 / 1254 / 395
Регистрация: 02.08.2011
Сообщений: 3,723
14.07.2017, 03:53 6
Цитата Сообщение от DarkOrk Посмотреть сообщение
Where(x => x.FolderID == 0).ToArray()
Возможно, фильтр отсекает все папки, вроде бы по-умолчанию seed(начальное значение) для сущностей в EF =1. - Мм. не в ту сторону полез.
Когда вы выполняете перечисление по IQuerable в LINQ to Entities, то гарантированно идет запрос в таблицу БД и получение сущностей.
Хотя у меня был какой-то баг в одном проекте MVC где во вьюхе почему-то все равно оставались proxy-классы. Решал вроде через EnableProxyCreation = false, но у вас, думаю такого не должно быть, да вам и не надо выключать lazy loading.

Добавлено через 6 минут
Цитата Сообщение от DarkOrk Посмотреть сообщение
....а при обработки, юзая поле _testFolders вложенных элементов нет
А в базе есть эти сущности?

Добавлено через 7 минут
Как вариант, попробуйте обойтись без Include-ов, а просто передавая IQuerable куда нужно, и выполняя перечисление там.
О каком типе проекта идет речь?

Добавлено через 7 минут
Btw, если называть ключи соблюдая convention, (TestFolderId вместо ID), можно сэкономить на написании кода во Fluent API.
0
DarkOrk
17 / 17 / 8
Регистрация: 06.02.2015
Сообщений: 353
14.07.2017, 04:00  [ТС] 7
В базе есть! 100% Все элементы, на этапе "3" отображаются и есть! всё корректно. Там есть по 3, по 4 вложенности - всё отлично! как только пропадает контекст (выходим за юзинг) все вложенности - падают.
0
IamRain
1407 / 1254 / 395
Регистрация: 02.08.2011
Сообщений: 3,723
14.07.2017, 04:17 8
Раз уж lazy loading не используется, то выключите его в данном месте (а потом включите, если надо). Видимо, из за этого вне using-а virtual сущности зануляются. Думаю, это сработает.
C#
1
context.Configuration.LazyLoadingEnabled = false;
Либо
C#
1
context.Configuration.ProxyCreationEnabled = false;
0
DarkOrk
17 / 17 / 8
Регистрация: 06.02.2015
Сообщений: 353
14.07.2017, 04:23  [ТС] 9
IamRain, Вот приложил 2 картиночки. 1я там где в блоке юзинг (то есть, контекст ещё существует), вторая, в том же методе, но за блоком юзинг.

p.s. вы будете сетовать на то что я вам показываю разные елементы выборки (1й вариант 0й элемент, во втором же варианте 1й елемент), но иначе я не могу, т.к. после потери контекста, он теряет произвольные елементы. Да! не все! Часть выгруженных данных есть и она корректна, но другая часть потеряна.... на момент работы с контекстом.
И в процессе мы имеем ошибку - System.ObjectDisposedException: 'The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.'
0
Миниатюры
EF, загрузка модели   EF, загрузка модели  
IamRain
1407 / 1254 / 395
Регистрация: 02.08.2011
Сообщений: 3,723
14.07.2017, 04:26 10
Я же вам сказал, выключите создание прокси классов, либо lazy целиком, тогда все сразу загрузится и все, сразу после создания контекста, в коде я этого не вижу.
0
DarkOrk
17 / 17 / 8
Регистрация: 06.02.2015
Сообщений: 353
14.07.2017, 04:41  [ТС] 11
IamRain, смотрите то в чём штука. Ок, сделаю как вы сказали (зачем лейзи-лоадинг понятно, про прокси классы я вообще не знаю - если в 2х словах можно написать - напишите, ну или потом погуглю).
Да, я написал, вот код теперь вот так выглядит

C#
1
2
3
4
5
6
7
8
9
10
            using (var context = new DbContext())
            {
                context.Configuration.LazyLoadingEnabled = false;
                context.Configuration.ProxyCreationEnabled = false;
                _testFolders = context
                    .TestFolders
                    .Include(x => x.FolderContains)
                    .Include(x=>x.FolderParent)
                    .Where(x => x.FolderID == 0).ToArray();
            }
Прокси классов нет, есть только мои модельки - здорво! НО! дело то в том что там где раньше был ерор с диспосом (как на скрине выше) теперь просто отсутствие данных! NULL и всё тут. Как будто их нет!
Но в базе они есть! и на момент "живого контекста" данные тоже есть, а потом, он мне говорит (уже с отключенным контекстом) - чувак, а тут у тебя вообще данных нет!
-Хотя были с "живым контекстом"
-И открыв базу и найдя этот же айдишник - они тоже есть.

Проблема явно не в этом...

Добавлено через 1 минуту
Причём повторюсь, он, раньше, сразу и первую вложенность терял. А теперь теряет (с инклудом) "произвольно глубокую".

Добавлено через 7 минут
Так же, всё же, повторюсь - он теряет произвольные вложенности, каждый раз после выборки, может какая-то тут проблема? может он их не догружает? (хотя тут вроде асинхронности нет, после вызова ToArray )
0
IamRain
1407 / 1254 / 395
Регистрация: 02.08.2011
Сообщений: 3,723
14.07.2017, 05:01 12
Просто тут древовидная структура, получается так, что мы не можем бесконечно указывать Include-ы, для подгрузки всех данных произвольной глубины. Предположительно.
Очевидно решением будет подгружать Include-ами только узлы корневой папки, затем при раскрытии какого-либо из подузлов подгружать уже его собственные подузлы. И так далее, то есть одного уровня вложенности вполне хватит.
1
DarkOrk
17 / 17 / 8
Регистрация: 06.02.2015
Сообщений: 353
14.07.2017, 15:02  [ТС] 13
IamRain, в общем, благодарен вам за т.с. "попытки" мне помочь, эт тоже важно с кем-то поговорить когда свои решения закончились. Thx!
0
Usaga
Эксперт .NET
5307 / 3614 / 632
Регистрация: 21.01.2016
Сообщений: 14,354
Завершенные тесты: 2
15.07.2017, 05:08 14
Лично я так и не смог въехать, в чём была проблема
0
DarkOrk
17 / 17 / 8
Регистрация: 06.02.2015
Сообщений: 353
15.07.2017, 05:13  [ТС] 15
Usaga, проблема не "была", проблема - есть.

....ну как бы.... сложно объяснить если все эти посты + скрины вам не дали понятия о данной проблеме, то я даж фиг его...

Если вы 2х словах, то:
если не заюзать, при выборке, метод .Include то навигационные свойства сами-по себе, отвалятся.
если заюзать - то будут.
а я столкнулся с тем, что навигационные свойства, отваливаются, в произвольном порядке, даже если заюзать метод .Include в случае если мы используем древовидную структуру элементов (ну или "вложенную"), когда элемент А имеет ссылку на такого же типа элемент (и таких вложенностей, не ограниченное кол-во).
Всё - проще не объясню
0
Usaga
Эксперт .NET
5307 / 3614 / 632
Регистрация: 21.01.2016
Сообщений: 14,354
Завершенные тесты: 2
15.07.2017, 05:23 16
Цитата Сообщение от DarkOrk Посмотреть сообщение
если не заюзать, при выборке, метод .Include то навигационные свойства сами-по себе, отвалятся.
Всё верно. Прокси используют контекст для доступа к данными. Если контекст задиспозить, то прокси тоже не смогут работать. Вам нужно вручную творить Include над всем navigation property, что собираетесь использовать. Или загружайте их позже (Load()).

Добавлено через 2 минуты
Или продлите жизнь контексту (это тоже допустимо).
0
kolorotur
Эксперт .NET
11116 / 9061 / 2285
Регистрация: 17.09.2011
Сообщений: 15,606
Завершенные тесты: 1
19.07.2017, 12:52 17
Лучший ответ Сообщение было отмечено DarkOrk как решение

Решение

Цитата Сообщение от DarkOrk Посмотреть сообщение
C#
1
2
3
4
5
6
7
8
9
10
            using (var context = new DbContext())
            {
                context.Configuration.LazyLoadingEnabled = false;
                context.Configuration.ProxyCreationEnabled = false;
                _testFolders = context
                    .TestFolders
                    .Include(x => x.FolderContains)
                    .Include(x=>x.FolderParent)
                    .Where(x => x.FolderID == 0).ToArray();
            }
Судя по тому, что вы выгружаете все папки нулевого уровня и по тому, что вы потом хотите использовать дерево без контекста, вам надо всегда выгружать всю таблицу — это автоматом подключит все навигационные свойства.
Два шага:
1. context.Database.LazyLoadingEnabled = false;
2.
C#
1
2
3
4
5
6
7
8
            using (var context = new DbContext())
            {
                context.Configuration.LazyLoadingEnabled = false;
                _testFolders = context
                    .TestFolders
                    .AsEnumerable()
                    .Where(x => x.FolderID == 0).ToArray();
            }
1
19.07.2017, 12:52
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.07.2017, 12:52

Загрузка 3D-модели в проект WPF
Всем привет! Можно ли загрузить 3д модель в проект WPF, какого формата, и...

Загрузка модели в формате STEP
Приветствую, есть ли готовые решения для загрузки модели в данном формате,...

Opengl es : Загрузка 3D модели в приложение
Всем привет!!! начинаю разбираться с графикой под android, но столкнулся с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru