仅将必要的数据Linq加载到Sql和ExpandoObject

时间:2017-02-09 21:53:37

标签: c# linq linq-to-sql

我正在尝试从以下(简化)查询中减少sql server调用:

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时,它不是仅提取用户displayname,而是完全填充User记录以获取显示名称。我尝试使用匿名类型来获取显示名称,但之后我无法使用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 个答案:

答案 0 :(得分:1)

如果您不需要整个用户实体,请创建一个仅包含您需要并投射到其中的字段的类型

Activity