2014-04-16 121 views
2

我正在學習Linq到自己的實體,我有一個問題。看看下面的方法。它會爲List of WorkflowsInProgress中的每個項目返回最近完成的任務。此方法正在使用其他方法調用,其中我使用的是fields of TasksInProgress,但我也使用the linked Tasks and WorkflowInProgress的屬性。如您所見,我已將Include添加到查詢中。Linq to Entities 4.0('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; 
    } 

我的問題是:

'有沒有更優雅的方式,包括查詢內的其他表?' 因爲我不喜歡那些剛剛坐在那裏的硬編碼對象名'(想象一下,如果表名更改...)

或者是否有任何其他方式可以用來包含鏈接對象/導航屬性的字段?

注意:這一個以上的梅索德的示例:

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的參數似乎沒有被工作由於這樣的事實它只有字符串除外(見下圖):enter image description here

+0

請檢查這個答案在這裏http://stackoverflow.com/questions/6102909/entity-framework-include-strongly-typed#answer-10843340 – NightOwl89

+0

你使用什麼版本的實體框架? – Loetn

+0

EF 4.0 =>這是公司內最新的分佈式版本。 – User999999

回答

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) 

我沒有測試它,但它應該工作。

+0

你不必做你自己的擴展方法。使用EF – Murdock

+0

內置的這已經內置在實體框架中。請參閱@ Murdock的答案。 – Loetn

+0

在舊版本中,此方法不存在。 – Alberto

4

編輯:將問題更改爲實體框架4.0之前的答案。這將僅適用於EF 4.1及更高版本

你可以有

.Include(o => o.Tasks) 

如果你至少你沒有使用字符串再加入

using System.Data.Entity; 

,你會得到,如果表變化的錯誤

+0

發現我在互聯網上,並試圖。但是,Include方法只接受一個字符串作爲參數。不是Lambda表達式(即使添加了System.Data.Entity)。還是有另一個命名空間需要?我將爲我的問題添加一個截圖。 – User999999

+0

@svranken您是否使用EF 4.1或更高版本? – Loetn

+0

@svranken方法簽名:public static IQueryable 包含(此IQueryable 源,Expression > path)其中T:class;在System.Data的QueryableExtensions中。實體 – Murdock