3

我有一个相当复杂的 linq 到我正在执行的实体查询,最后,我有一个结果集。我遍历该结果集,构建业务对象并返回该业务对象列表。它很快,问题是 2 个子属性是具有自己子对象的复杂对象。对于循环中的每个业务对象,我必须进行 2 次 DB 调用来填充其子对象。这两个电话减慢了整个过程,有没有更好的方法来做到这一点?这里是EF的菜鸟。(EF 4,SQL Server 2008,c#)

获取结果集:

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;

有没有更好的办法?

4

2 回答 2

2

只需将其添加.Include("Domains").Include("DomainEntries")到您的 Linqin 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

于 2013-04-10T18:22:16.567 回答
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

您可以引入Include假设选择所有员工及其部门。如果您有导航属性,则根本不需要加入。您可以像这样使用包含:

List<Employee> employeesWithDepartments = CreateObjectSet<Employee>().
                                      Include(e => e.Department).
                                      ToList();
于 2013-09-25T16:33:56.780 回答