2012-06-21 2 views
0

настоящее время у меня следующий код в моем проектеПовышение производительности EF запрос

public List<PermissionValue> GetUnderlyingPermissionsForUser(string userName, int guiPermissionTypeId, int productTypeId) 
    { 
     using (CliVeEntities db = new CliVeEntities()) 
     {    
      var listUnderlyings = (from gui in db.GuiPermissionUnderlying 
           join bue in db.BranchUsersExternal on gui.BranchUsersId equals bue.BranchUsersID  
           join bu in db.BranchUsers on bue.BranchUsersID equals bu.BranchUsersId 
           where bu.UserName == userName && gui.ViewTypeId == guiPermissionTypeId 
           && gui.UnderlyingId.HasValue 
           && !gui.SectorId.HasValue 
           && gui.ProductTypeId == null 
           && gui.ProductGroupId == null 
           select new PermissionValue { Id = gui.UnderlyingId.Value, Visible = gui.value}).ToList<PermissionValue>(); 


      var listUnderlyingsProductGroup = (from gui in db.GuiPermissionUnderlying 
               join bue in db.BranchUsersExternal on gui.BranchUsersId equals bue.BranchUsersID 
               join bu in db.BranchUsers on bue.BranchUsersID equals bu.BranchUsersId 
               join pg in db.ProductGroup on gui.ProductGroupId equals pg.ProductGroupId 
               join pt in db.ProductType on pg.ProductGroupId equals pt.ProductGroupId 
               where bu.UserName == userName && gui.ViewTypeId == guiPermissionTypeId 
               && gui.UnderlyingId.HasValue 
               && !gui.SectorId.HasValue 
               && pt.ProductTypeId == productTypeId 
               select new PermissionValue { Id = gui.UnderlyingId.Value, Visible = gui.value }).ToList<PermissionValue>(); 




      var listUnderlyingsProductType = (from gui in db.GuiPermissionUnderlying 
               join bue in db.BranchUsersExternal on gui.BranchUsersId equals bue.BranchUsersID 
               join bu in db.BranchUsers on bue.BranchUsersID equals bu.BranchUsersId 
               where bu.UserName == userName && gui.ViewTypeId == guiPermissionTypeId 
               && gui.UnderlyingId.HasValue 
               && !gui.SectorId.HasValue 
               && gui.ProductTypeId == productTypeId 
               select new PermissionValue { Id = gui.UnderlyingId.Value, Visible = gui.value }).ToList<PermissionValue>(); 


      var listUnderlyingsForSectors = (from gui in db.GuiPermissionUnderlying 
              join bue in db.BranchUsersExternal on gui.BranchUsersId equals bue.BranchUsersID 
              join bu in db.BranchUsers on bue.BranchUsersID equals bu.BranchUsersId 
              join u in db.Underlying on gui.SectorId equals u.SectorId 
              where bu.UserName == userName && gui.ViewTypeId == guiPermissionTypeId 
              && !gui.UnderlyingId.HasValue 
              && gui.ProductTypeId == null 
              && gui.ProductGroupId == null 
              select new PermissionValue { Id = u.UnderlyingId, Visible = gui.value }).ToList<PermissionValue>(); 


      var listUnderlyingsForSectorsProductGroup = (from gui in db.GuiPermissionUnderlying 
                 join bue in db.BranchUsersExternal on gui.BranchUsersId equals bue.BranchUsersID 
                 join bu in db.BranchUsers on bue.BranchUsersID equals bu.BranchUsersId 
                 join u in db.Underlying on gui.SectorId equals u.SectorId 
                 join pg in db.ProductGroup on gui.ProductGroupId equals pg.ProductGroupId 
                 join pt in db.ProductType on pg.ProductGroupId equals pt.ProductGroupId 
                 where bu.UserName == userName && gui.ViewTypeId == guiPermissionTypeId 
                 && !gui.UnderlyingId.HasValue 
                 && pt.ProductTypeId == productTypeId 
                 select new PermissionValue { Id = u.UnderlyingId, Visible = gui.value }).ToList<PermissionValue>(); 

      var listUnderlyingsForSectorsProductType = (
                 from gui in db.GuiPermissionUnderlying 
                 join bue in db.BranchUsersExternal on gui.BranchUsersId equals bue.BranchUsersID 
                 join bu in db.BranchUsers on bue.BranchUsersID equals bu.BranchUsersId 
                 where bu.UserName == userName && gui.ViewTypeId == guiPermissionTypeId 
                 && !gui.UnderlyingId.HasValue 
                 && gui.SectorId.HasValue 
                 && gui.ProductTypeId == productTypeId 
                 select new PermissionValue { Id = gui.UnderlyingId.Value, Visible = gui.value }).ToList<PermissionValue>(); 

      var mergeList1 = MergeAndDistinctList(listUnderlyings, listUnderlyingsProductType); 
      var mergeList2 = MergeAndDistinctList(mergeList1, listUnderlyingsProductGroup); 
      var mergeList3 = MergeAndDistinctList(mergeList2, listUnderlyingsForSectors); 
      var mergeList4 = MergeAndDistinctList(mergeList3, listUnderlyingsForSectorsProductType); 
      var resultMergeList = MergeAndDistinctList(mergeList4, listUnderlyingsForSectorsProductGroup); 

      return resultMergeList; 

И это код для моей функции MergeAndDistinctList

protected List<PermissionValue> MergeAndDistinctList(List<PermissionValue> listPrimary, List<PermissionValue> listSecondry) 
    { 
     List<PermissionValue> listMergedAndDistinct = new List<PermissionValue>(); 

     listMergedAndDistinct.AddRange(listPrimary); 

     var filter = listPrimary.Select<PermissionValue, int>(p => p.Id); 
     listMergedAndDistinct.AddRange(listSecondry.Where<PermissionValue>(p => !filter.Contains(p.Id)).Select(p => p)); 
     return listMergedAndDistinct; 
    } 

Моя проблема с моим GetUnderlyingsForClient (код), что ему попадает в базу данных несколько раз. Если этот метод сильно ударит, это может привести к нескольким вызовам в базе данных.

Кто-нибудь знает какие-либо способы сделать этот код более эффективным и уменьшить количество вызовов БД, которые я должен сделать.

+0

Вы отказались от жизненно важной части - в чем разница между запросами? Можете ли вы принести все результаты (например, используя где PK вместо PK =) и разделите их позже? –

+0

Без сведений о том, как каждый запрос отличается, мы не можем сказать, есть ли способ оптимизации метода или нет. Даже если вы уменьшите его до одного запроса, вы можете обнаружить, что несколько небольших быстрых запросов превосходят одиночные массивные запросы. Ваша оптимизация может заключаться в реализации кэширования, так что несколько обращений к методу доступа к кешированным результатам, а не к зависящим. Недавно я написал сообщение о первичной оптимизации, в которой может помочь. [link] (http://www.thinqlinq.com/Post.aspx/Title/LINQ-to-Database-Performance-hints) –

+0

Я обновил выше, чтобы получить полный запрос. Надеюсь, это поможет вам помочь :) – caa

ответ

0

кажется, что вы делаете много запросов на одной и те же таблицы (а в вашем случае)

Для ограничения запросов к базе данных, вы можете получить все необходимые данные в локальном списке, и использовать этот список для нескольких запросов как это:

var MyBaseList = db.A.ToList(); 

var listUnderlyings = (from a MyBaseList [...] 
var listUnderlyingsProductGroup = (from a MyBaseList [...] 

А для предела поиска данных, фильтр MyBaseList, чтобы получить только строки, используемые следующие запросы.

+0

Если у A есть намного больше записей, чем необходимо, это приведет к ужасной производительности! –

0

Вы можете Union ваши запросы следуя упрощенной схемы:

(from a in As where a.Id > 0 select a) 
.Union(
from a in As where a.Name == "a" select a) 
.Union(
... 
) 
.Select(a => new { a.x, a.y }) 
.Distinct() 

Union является слияние части вашей MergeAndDistinctList и Distinct, эхм, отчетливая частью. Хорошая вещь: Distinct выполняется над проекцией (Id и Visible в вашем случае).

Теперь все должно выполняться в одном (чудовищном) запросе без промежуточного принудительного выполнения, вызванного AddRange в MergeAndDistinctList.

Глядя на ваши вопросы, я чувствую, что вы можете сделать это с меньшим количеством из них, объединив некоторые условия, но это зависит от вас.

Смежные вопросы