【问题标题】:Linq to Entities 4.0 ('Include'): In search of an elegant wayLinq to Entities 4.0('Include'):寻找一种优雅的方式
【发布时间】:2014-04-16 08:19:16
【问题描述】:

我正在自学 Linq to entity,我有一个问题。看看下面的方法。它返回 List of WorkflowsInProgress 中每个项目的最新完成任务。此方法在我使用fields of TasksInProgress 的其他方法中被调用,但我也在使用the linked Tasks and WorkflowInProgress 的属性。如您所见,我已将Include 添加到查询中。

    public List<TasksInProgress> GetLatestTaskForWorkflowsInProcess(List<WorkflowInProgress> pWorkflowsInProcess)
    {
        List<TasksInProgress> tasksLst = new List<TasksInProgress>();
        List<Int64> workflowIds = pWorkflowsInProcess.Select(w => w.Id).ToList();
        using (TaskWorkflowEntities myDatacontext = new TaskWorkflowEntities())
        {

            tasksLst = (from taskP in myDatacontext.TasksInProgress.Include("Tasks").Include("WorkflowInProgress")
                        where (taskP.RunningState == (int)WorkflowRunningStates.Completed) &&
                        workflowIds.Contains(taskP.WorkflowInProgressId) &&
                        taskP.Completed == (from sTaskP in myDatacontext.TasksInProgress
                                          where sTaskP.WorkflowInProgressId == taskP.WorkflowInProgressId
                                          group sTaskP by sTaskP.WorkflowInProgressId into gSTaskP
                                          select gSTaskP.Max(g => g.Completed)).FirstOrDefault()
                        select taskP).ToList<TasksInProgress>();
        }

        return tasksLst;
    }

我的问题是:

'有没有更优雅的方式在 Query 中包含其他表?' 因为我不喜欢那些硬编码的对象名只是坐在那里'(想象一下如果表名改变......)

或者还有其他方法可以用来包含链接对象/导航属性的字段吗?

注意:以上方法示例:

foreach(TasksInProgress taskInProc in _taskWorkflowS.GetLatestTaskForWorkflowsInProcess(currentWorkflowsInProcess))
{
   //Do something with (int)taskInProc.Tasks.TaskOrder
   //Do something with taskInProc.WorkflowInProgress.WorkflowId
   // ...

   //for Instance
   int i = 0;
   i = _taskWorkflowS.GetAmountOfTasksForWorkflow(taskInProc.WorkflowInProgress.WorkflowId, (int)taskInProc.Tasks.TaskOrder)

   if (i > 0 ) 
   { ... }
}

更新: 使用 lambda 表达式作为 Include 的参数似乎不起作用,因为它只排除字符串(见下图):

【问题讨论】:

  • 请在此处查看此答案stackoverflow.com/questions/6102909/…
  • 您使用的是哪个版本的实体框架?
  • EF 4.0 => 这是公司内部的最新分发版本。
  • 那你必须使用@Alberto提出的解决方案。

标签: c# linq entity-framework


【解决方案1】:

编辑:在问题更改为实体框架 4.0 之前回答。这仅适用于 EF 4.1 及更高版本

你可以拥有

.Include(o => o.Tasks)

如果你添加

using System.Data.Entity;

至少那时你没有使用字符串,如果表格发生变化,你会得到错误

【讨论】:

  • 在互联网上找到我并尝试过。但是 Include 方法只接受一个字符串作为参数。不是 Lambda 表达式(即使添加了 System.Data.Entity)。或者是否需要另一个命名空间?我会在我的问题中添加一个截图。
  • @svranken 您使用的是 EF 4.1 或更高版本吗?
  • @svranken 方法签名:public static IQueryable Include(this IQueryable source, Expression> path) where T : class;在 System.Data.Entity 中的 QueryableExtensions 中
  • EF 4.0 => 这是公司内部最新的分布式版本。为什么我们总是落后于最新技术......
  • @svranken 对不起,伙计,那这行不通,然后我建议您选择其他答案。
【解决方案2】:

您可以编写一个使用 lambda 表达式而不是字符串的扩展方法:

public static ObjectQuery<T> Include<T>(this ObjectQuery<T> query, Expression<Func<T, object>> selector)
{
    MemberExpression body = selector.Body as MemberExpression;
    return query.Include(body.Member.Name);

}

并像这样使用它:

myDatacontext.TasksInProgress.Include(q=>q.Tasks)
                             .Include(q=>q.WorkflowInProgress)

我没有测试过,但应该可以。

【讨论】:

  • 您不必自己做扩展方法。使用EF内置的
  • 这已经内置在实体框架中。请参阅@Murdock 的回答。
  • 在旧版本中此方法不存在。
  • 你是对的。 :) 也许您可以将此添加到您的答案中?
猜你喜欢
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
相关资源
最近更新 更多