Как сделать запрос LINQ с Unions более эффективным - PullRequest
0 голосов
/ 26 апреля 2019

Я унаследовал запрос LINQ ниже и чувствую, что запрос может быть реорганизован для эффективности. В настоящее время запрос занимает около 6-8 секунд времени обработки, чтобы вернуть одну запись пользователю во внешней части приложения. LINQ - не моя сильная сторона, поэтому любая помощь будет принята с благодарностью.

Запрос должен в конечном итоге создать отдельный список объектов CA_TASK_VW, которые связаны со списком различных CA_OBJECT_ID, полученных из таблиц CA_OBJECT, CA_PEOPLE и CA_CONTRACTOR.

var data = (from a in _db.CA_TASK_VW
                    where a.TASK_TYPE == "INSPECTION" && a.TASK_AVAILABLE_FLAG == "Y" && a.TARGET_END_DATE == null
                    select a).AsQueryable();

data = data.Join(_db.CA_OBJECT.Where(o => o.ENTERED_BY == _userId),
                o => o.CA_OBJECT_ID, p => p.CA_OBJECT_ID,
                (t, p) => t)
            .Union(data.Join(_db.CA_PEOPLE.Where(p => p.EMAIL == _email),
                t => t.CA_OBJECT_ID, p => p.CA_OBJECT_ID,
                (t, p) => t))
            .Union(data.Join(_db.CA_CONTRACTOR.Where(c => c.CONTRACTOR.EMAIL == _email),
                t => t.CA_OBJECT_ID, c => c.CA_OBJECT_ID,
                (t, c) => t));

Ответы [ 2 ]

1 голос
/ 26 апреля 2019

Код, похоже, использует Join / Union для выполнения в основном предиката where в списке CA_TASK_VW, поэтапно фильтруя его до конечного результата, так что произойдет, если вы просто укажете условие whereнапрямую?

var data = from a in _db.CA_TASK_VW
           where a.TASK_TYPE == "INSPECTION" && a.TASK_AVAILABLE_FLAG == "Y" && a.TARGET_END_DATE == null
           select a;

data = data.Where(t => _db.CA_OBJECT.Where(o => o.ENTERED_BY == _userId).Select(o => o.CA_OBJECT_ID).Contains(t.CA_OBJECT_ID) ||
                       _db.CA_PEOPLE.Where(p => p.EMAIL == _email).Select(p => p.CA_OBJECT_ID).Contains(t.CA_OBJECT_ID) ||
                       _db.CA_CONTRACTOR.Where(c => c.CONTRACTOR.EMAIL == _email).Select(c => c.CA_OBJECT_ID).Contains(t.CA_OBJECT_ID));
0 голосов
/ 26 апреля 2019

Вы можете попробовать использовать UNION ALL, если вам не нужны дубликаты в результатах запроса, так как он работает намного быстрее, чем UNION

...