2

I'm learning Linq to entities on my own and I have a bit of a question. Take a look at the following method. It returns the latest completed task for every item inside the List of WorkflowsInProgress . This method is being called within an other method where i'm using the fields of TasksInProgress , but i'm also using properties of the linked Tasks and WorkflowInProgress. As you will see I've added the Include to the query.

    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;
    }

My Question is:

'Is there a more elegant way to include other tables inside a Query?' Because i don't like those hardcoded objectnames just sitting there' (Imagine if the tablename changes...)

Or is there any other way that i can use to include the fields of linked objects/navigational properties?

Note: Example of the methode above this one:

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 ) 
   { ... }
}

Update: using lambda expression as parameter of the Include doesn't appear to be working due to the fact that it only excepts string (see image below):enter image description here

User999999
  • 2,500
  • 7
  • 37
  • 63

2 Answers2

4

Edit: Answer before the question was changed to Entity Framework 4.0. This will only work for EF 4.1 and later

You can have

.Include(o => o.Tasks)

if you add

using System.Data.Entity;

at least you are not using strings then and you will get errors if the table changes

Murdock
  • 4,352
  • 3
  • 34
  • 63
  • found i on the internet and tried that. But the Include method accepts only a single string as parameter. Not a Lambda expression (even with adding System.Data.Entity). Or is there another namespace required? I will add a screenshot of this to my question. – User999999 Apr 16 '14 at 08:41
  • @svranken Are you using EF 4.1 or later? – Loetn Apr 16 '14 at 08:44
  • @svranken Method signature: public static IQueryable Include(this IQueryable source, Expression> path) where T : class; in QueryableExtensions in System.Data.Entity – Murdock Apr 16 '14 at 08:46
  • EF 4.0 => This is the latest distributed version within the company. Why are we always so far behind on the latest technologies .... – User999999 Apr 16 '14 at 08:47
  • @svranken sorry mate then this don't work then I suggest you go with the other answer. – Murdock Apr 16 '14 at 08:50
  • Thnx for the help! I'll give Alberto's solution a shot. – User999999 Apr 16 '14 at 08:51
2

You can write an extension method that use a lambda expression instead of a string:

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);

}

and use it like:

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

I have not tested it, but it should work.

User999999
  • 2,500
  • 7
  • 37
  • 63
Alberto
  • 15,626
  • 9
  • 43
  • 56