2013-04-10 55 views
2

的更有效的方式我有一個相當複雜的LINQ到我演出單位查詢,到最後,我有一個結果集。我遍歷該結果集,構建業務對象並返回該業務對象列表。它非常快,問題在於2個子屬性是帶有自己的子對象的複雜對象。對於我的循環中的每個業務對象,我必須進行2個DB調用來填充其子對象。這兩個調用減慢了整個過程,有沒有更好的方法來做到這一點?這裏的菜鳥到EF。 (EF 4,SQL Server 2008中,C#)裝載兒童LINQ實體對象以實體查詢

得到一個結果集:

var newresult = from r in result // result is another complex query 
      join subedit in 
       (from sa in context.Security_Access 
       join g in context.Security_UserGroup on sa.EntityID equals g.GroupID 
       where (sa.PrivledgeID == xx) && g.UserID == userId 
       select new { user = g.UserID, linkid = sa.LinkID }).Distinct() on new { aid = r.AssetId } equals new { aid = subedit.linkid } into theSubEdit 
      from subEditAccess in theSubEdit.DefaultIfEmpty() 
      join subdownload in 
       (from sa in context.Security_Access 
       join g in context.Security_UserGroup on sa.EntityID equals g.GroupID 
       where (sa.PrivledgeID == xx|| sa.PrivledgeID == yy) && g.UserID == userId 
       select new { user = g.UserID, linkid = sa.LinkID }).Distinct() on new { aid = r.AssetId } equals new { aid = subdownload.linkid } into theSubDownload 
      from subDownloadAccess in theSubDownload.DefaultIfEmpty() 
      join subView in 
       (from sa in context.Security_Access 
       join g in context.Security_UserGroup on sa.EntityID equals g.GroupID 
       where (sa.PrivledgeID == xx|| sa.PrivledgeID == yy|| sa.PrivledgeID == 101) && g.UserID == userId 
       select new { user = g.UserID, linkid = sa.LinkID }).Distinct() on new { aid = r.AssetId } equals new { aid = subView.linkid } into theSubView 
      from subViewAccess in theSubView.DefaultIfEmpty() 
      select new { r, EditAccess = (int?)subEditAccess.user, DownloadAccess = (int?)subDownloadAccess.user, ViewAccess = (int?)subViewAccess.user }; 

我再通過該結果集循環:

foreach (var asset in newresult) 
{ 
    // and build a new business object, set its properties 
    BoAsset boAsset = new BoAsset(); 
    boAsset.HasEditRights = (asset.EditAccess > 0); 
    boAsset.HasDownloadRights = (asset.DownloadAccess > 0); 
    boAsset.HasViewRights = (asset.ViewAccess > 0); 
    boAsset.Description = asset.r.Description; 
    boAsset.DetailedDescription = asset.r.DetailedDescription; 
    boAsset.Keywords = asset.r.Keywords; 
    boAsset.Notes = asset.r.Notes; 
    boAsset.Photographer = asset.r.Photographer; 
    boAsset.PhotographerEmail = asset.r.PhotographerEmail; 
    boAsset.Notes = asset.r.Notes; 
    boAsset.Author = asset.r.Author; 

    // these 2 properties i've commented out are 
    // complex objects/entities, setting them the way I am 
    // requires me to call 2 separate methods which make 2 DB trips 
    // per business object. 

    //boAsset.Domains = GetAssetDomains(asset.r.AssetId); 
    //boAsset.DomainEntries = GetAssetCustomDomains(asset.r.AssetId); 

    myListofObjects.Add(boAsset); 
} 
return myListofObjects; 

有沒有更好的辦法?

回答

1

只需將此.Include("Domains").Include("DomainEntries")添加到您的Linq in in context.Security_Access這應該從這些表中一行一行地獲取行。

所以你的「內部」查詢看起來像:

from sa in context.Security_Access.Include("Domains").Include("DomainEntries") 
join g in context.Security_UserGroup on sa.EntityID equals g.GroupID 
where (sa.PrivledgeID == xx) && g.UserID == userId 
select new { ... 

下面是從MS文檔:http://msdn.microsoft.com/en-us/library/bb738708.aspx

+0

謝謝,我會嘗試這並標記你的答案,如果一切順利 – TheRedDwarf

+0

我不明白,我應該如何使用這個......我有一個名爲方法GetDomains(int assetid)返回一個對象列表,我如何將它加入到這個? – TheRedDwarf

+0

我的假設是'Domains'是你的DB中的一個表,'Security_Access'表中有一個該表的外鍵。使用'Include(「Domains」)'wouls只需將該表中的相關行添加到結果中,這樣就不需要'GetDomains'方法。如果是這種情況並非如此,你的數據庫結構是不同的,你可能會無法使用'.INCLUDE()' – Floremin

0

如果你想提高你的表現使用編譯查詢!

你可以在這裏檢查的例子。

static readonly Func<AdventureWorksEntities, Decimal, 
IQueryable<SalesOrderHeader>> s_compiledQuery2 = 
CompiledQuery.Compile<AdventureWorksEntities, Decimal, IQueryable<SalesOrderHeader>>((ctx, total) => 
from order in ctx.SalesOrderHeaders.Include("Orders") where order.TotalDue >= total select order); 

MSDN

您能介紹包括想選擇所有的員工與他們一起的部門。如果您有導航屬性,則根本不需要加入。您可以使用包含這樣的:

List<Employee> employeesWithDepartments = CreateObjectSet<Employee>(). 
             Include(e => e.Department). 
             ToList();