[英]Increase EF query performance
我的項目中目前有以下代碼
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()代碼的問題是它多次擊中數據庫。 如果此方法受到很大的打擊,那么這可能會轉換為對數據庫的多次調用。
是否有人知道有什么方法可以使此代碼更高效並減少我必須進行的數據庫調用量。
似乎您在同一張表上進行了很多查詢(在您的情況下為a)
為了限制數據庫查詢,您可以在本地列表中獲取所需的所有數據,並將此列表用於多個查詢,如下所示:
var MyBaseList = db.A.ToList();
var listUnderlyings = (from a MyBaseList [...]
var listUnderlyingsProductGroup = (from a MyBaseList [...]
為了限制數據檢索,請過濾MyBaseList以僅獲取以下查詢使用的行。
你可以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
的合並部分,是不同的部分。 妙處是:在投影上進行了區分(在您的情況下為ID和Visible)。
現在,所有操作都應在一個( AddRange
)查詢中執行,而沒有由MergeAndDistinctList中的AddRange
引起的中間強制執行。
查看您的查詢,我覺得您可以通過組合一些條件來處理較少的查詢,但這取決於您。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.