Соедините два стола с меньшим временем - PullRequest
1 голос
/ 30 марта 2020

У меня есть две таблицы TableProject и TableFlag; Я хочу присоединиться к ним вместе с некоторыми условиями. Итак, сначала я получаю список из первой таблицы, затем проверяю вторую таблицу, чтобы найти правильное значение в a для l oop.

Хотя это работает, но довольно медленно, это занимает около 10 секунд.

// Step 1 get the list from the first table
var temp = Task.FromResult(await myDatabase.TableProject.
                Select(p => new ProjectDto
                {
                    Id = p.Id,
                    Name = p.Name,
                    Type = p.Type,
                    Status = p.Status
                })
                .Where(x => x.Type != 999)
                .Orderby(y => y.Name).ToListAsync());
var list = temp.Result;

// Step 2 check the second table to find right values in a for loop.
for(int i = 0; i < list.Count; i++)
{
    if(list[i].Type.HasValue)
    {
         list[i].ProjectType = (from f in myDatabase.TableFlag
                            where f.FlagName == "PROJECT TYPE" && f.FlagId == list[i].Type
                            select f.FlagValue).FirstOrDefaut();
    }
    if(list[i].Type.HasValue)
    {
         list[i].Status = (from f in myDatabase.TableFlag
                            where f.FlagName == "PROJECT STATUS" && f.FlagId == list[i].Status
                            select f.FlagValue).FirstOrDefaut();
    }
}       
return Json(list);          

Если вы посмотрите на шаг 2, потребуется время o (n ^ 2).

Обновление:

Sql запрос (T - SQL) приветствуется. Я могу использовать хранимую процедуру.

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Если вы используете предложения let, они будут преобразованы в объединения или подзапросы в базе данных. Это снизит количество обращений к базе данных, и запрос будет выполняться намного быстрее.

var query =
  from project in myDatabase.TableProject
  where project.Type != 999
  order by project.Name
  let statusFlag = myDatabase.TableFlag
    .FirstOrDefault(f => f.FlagName == "PROJECT STATUS" && f.FlagId == project.Status)
  let typeFlag = myDatabase.TableFlag
    .FirstOrDefault(f => f.FlagName == "PROJECT TYPE" && f.FlagId == project.Type)
  select new ProjectDto {
    Id = project.Id,
    Name = project.Name,
    Type = project.Type,
    Status = statusFlag?.FlagValue,
    ProjectType = typeFlag?.FlagValue
  };
1 голос
/ 30 марта 2020

Вы можете создать материализованное представление в БД, соединив две таблицы, и только затем получите результаты этого представления в своем приложении. Используйте https://docs.microsoft.com/en-us/sql/t-sql/statements/create-materialized-view-as-select-transact-sql?view=azure-sqldw-latest, если у вас SQL Сервер или https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_6002.htm, если у вас ORACLE DB. Материализованное представление намного быстрее, чем обычное представление или только соединение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...