Sanjay Dev Ответов: 1

Entity framework и много данных


Я использую первый подход к базе данных с базой данных SQLite. Данные распределены по нескольким таблицам. При извлечении данных для одного элемента мне нужно прочитать данные из всех таблиц и получить соответствующие данные. Я сталкиваюсь с проблемами при запросе огромного количества данных.

Что я уже пробовал:

У меня есть 3 таблицы транзакций, записей и полей.

Таблица транзакций - это основная таблица, содержащая транзакции с первичным ключом TransactionId (GUID). Этот же TransactionId используется в таблице записей как ForeignKey.

Таблица записей имеет RecordId (GUID)в качестве основного ключа, на который ссылается таблица полей.

Мне нужно получить одну транзакцию со всеми соответствующими записями и полями из БД на основе GUID, который передается в функцию.


Это код, который я пытаюсь выполнить

public Transaction LoadTransaction(Guid transactionId)
        {
                context.Fields.Load();
                context.Records.Load();
                var transaction = context.Transactions.ToList().Where(p => p.TransactionId == transactionId).OrderBy(o => o.CreationDate).FirstOrDefault();

                return transaction;
        }


Это прекрасно работает с меньшим количеством строк.Но при тестировании с 20k строками он терпит неудачу и выбрасывает исключение OutOfMemory, когда оно достигает
context.Fields.Load();


Таблица полей содержит все данные, а также данные изображений, что делает ее большой.

Это сгенерированный SQL-запрос, когда я получаю при наведении курсора мыши на оператор.

{SELECT 
[Extent1].[FieldId] AS [FieldId], 
[Extent1].[FieldNumber] AS [FieldNumber], 
[Extent1].[FieldValue] AS [FieldValue], 
[Extent1].[RecordId] AS [RecordId], 
[Extent1].[TransactionId] AS [TransactionId]
FROM [Field] AS [Extent1]}

Wendelius

Мало вопросов:
- сколько рядов вы пытаетесь набрать?
- как выглядит сгенерированный SQL?

Sanjay Dev

Я пытаюсь извлечь около 200 строк на основе условия из общего списка 20000+.

Сгенерированный SQL выглядит как обычный оператор Select со всеми именами столбцов. Перед запросом данных из основной таблицы я загрузил другие 2 таблицы с помощью .Загрузка, содержащая связанные данные.

Это как будто есть 3 стола. MainTable, DetailsTable и SubDetailsTable(детали, связанные с DetailsTable).

Я использовал для загрузки DetailsTable и SubDetailsTable usind. Load()

Затем запросите MainTable. Таким образом, я получаю связанные данные из двух других таблиц, в то время как я получаю один элемент из MainTable.

Исключение OutOfMemory приходит, когда дело доходит до связи.SubDetailsTable.Загрузка()

SubDetailsTable содержит 20K строк.

Wendelius

В общем, 20 000 строк в таблице-это мало, и вы получаете только 200 строк, так что все должно быть хорошо. Я имею в виду, что соединения правильно расположены, так что у вас нет декартова произведения. Можете ли вы опубликовать сгенерированный sql?

Sunasara Imdadhusen

Укажите точный запрос, который вы выполняете в базе данных

1 Ответов

Рейтинг:
2

Wendelius

Похоже, что вы извлекаете все строки из полей и записей отдельно и не присоединяете их к транзакции.

Что если вы попробуете немного другой синтаксис

var query = from t in context.Transactions
            join f in context.Fields on t.TransactionId equals f.TransactionId
            join r in context.Records in f.RecordId equals r.RecordId
            where t.TransactionId == transactionId
            select transaction;

Однако это вернет данные только из транзакции формы, поэтому, если вам нужны данные из других таблиц, вам также нужно соответствующим образом изменить выбранную часть.

[ДОПОЛНЕНИЕ]
var query = from t in context.Transactions
            join r in context.Records in t.TransactionId equals r.TransactionId
            join f in context.Fields on r.RecordId equals f.RecordId
            where t.TransactionId == transactionId
            select transaction;


Sanjay Dev

Попробовал выполнить запрос, как вы уже упоминали. Но он дает мне 0 результатов, когда я пытаюсь запросить существующие данные.

Я просто попробовал другой подход. Я попытался сопоставить результат запроса с объектом класса не сущностей.

string query = $"select * from 'Transaction' INNER JOIN 'Record' ON 'Record'.TransactionId = 'Transaction'.TransactionId INNER JOIN 'Field' ON 'Field'.RecordId = 'Record'.RecordId where 'Transaction'.TransactionId=X'370B46946DCEB240BBFF95CEB574A9FD' LIMIT 1";

var result = context.Database.SqlQuery<TestTransaction>(query).ToList();


Это дает мне исключение из памяти, источником которого является System.Data.Sqlite. Но запрос отлично работает в этом инструменте. Инструмент эксперт базы данных SQLite [^]

Я работаю над 32-битным приложением WPF. Может ли это быть проблемой?

Wendelius

Основываясь на вашем SQL, кажется, что соединения в моем исходном запросе LINQ были недействительными. Я обновил решение.

Также проверьте, что соединение действительно в момент выполнения запроса, что вы нигде его не закрыли..