2017-02-09 37 views
1

我想從以下(簡化)查詢減少SQL服務器的呼叫:僅加載必要的數據LINQ to SQL和ExpandoObject

var timequery = from t in TimeRecords 
       select t; 

var reducedResults = timequery.Select(delegate(TimeRecord t){ 

    ExpandoObject result = new ExpandoObject(); 
    IDictionary<string,object> record = (IDictionary<string,object>)result; 

    record["DisplayName"] = t.User.DisplayName; //this loads ENTIRE user record 

    //Include Dynamic columns 
    foreach (var expenseTypeDescription in usedExpenseTypes) //the usedExpenseTypes are the types in the results 
    {  
     //also loading entire expense and expense type records 
     record[expenseType] = t.Expenses.Where(e => e.ExpenseType.Description = expenseTypeDescription).Sum(e => e.Amount); 
    } 

    return (dynamic)result; 
}).ToList(); 

如果這有什麼差別,我會做reducedResults.OrderBy(t => t.Copies).Skip(page).Take(pageSize),其中副本是一個後面的代碼中的動態列中的費用類型。所以,我不想在分頁之前將所有結果放入內存中。

當我查看生成的sql,而不是拉動用戶顯示名時,它完全填充用戶記錄以獲取顯示名稱。我試圖通過匿名類型來獲取顯示名稱,但後來我無法使用delegate(TimeRecord t)。不使用委託將是好的,但我不知道如何執行費用類型的動態列與timequery.Select(t => new { t.User.DisplayName, //dynamic columns });

總而言之,如何不加載整個用戶記錄?

編輯: 簡體類型

class TimeRecord 
{ 
    User User; 
    EntitySet<Expense> Expenses; 
    //other stuff 
} 

class User 
{ 
    string DisplayName; 
    //other stuff 
} 

class Expense 
{ 
    decimal Amount; 
    ExpenseType ExpenseType; 
    //other stuff 
} 

class ExpenseType 
{ 
    string Description; 
    //other stuff 
} 

回答

1

如果你不需要整個用戶實體,創建一個包含你需要的領域,投給它的類型

public class UserInfo 
{ 
    public string DisplayName { get; set; } 
    //include anything else you may need. 
} 

var timequery = from t in TimeRecords 
       select new UserInfo 
       { 
       DisplayName = t.User.DisplayName 
       }; 
+0

這不是鑄造這完全是一個完全不同的概念。我會把它稱作投影。 – DavidG

+0

如何獲取動態費用列?或者我會打電話給動態代碼,並建立它? – SumGuy

+0

@SumGuy否,那隻會得到顯示名稱,並且您將無法訪問您稍後從中查詢的任何其他數據。你可以發佈你的表結構或類聲明... –