3

私が実行しているかなり複雑な linq to entity クエリがあり、最終的に結果セットがあります。その結果セットをループし、ビジネス オブジェクトを作成して、そのビジネス オブジェクトのリストを返します。問題は、2 つの子プロパティが独自の子オブジェクトを持つ複雑なオブジェクトであることです。ループ内のすべてのビジネス オブジェクトに対して、2 つの DB 呼び出しを行ってその子オブジェクトを埋める必要があります。これらの 2 つの呼び出しにより、プロセス全体が遅くなります。これを行うためのより良い方法はありますか? ここでEFへのnoob。(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

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();
于 2013-09-25T16:33:56.780 に答える