2014-04-08 62 views
4

我需要根據組ID,這些組ID被EMPNO擁有參加所有數據雙重過濾在LINQ

public IEnumerable<EmployeeWithEmail> GetAllEmployeesWithEmail(int EmpNo) 
{ 
    using (var context = new SQL_TA_SCOREBOARDEntities1()) 
    { 
     return (from ea in context.View_SystemAdminMembers 
       join vh in context.View_HCM on (Int16)ea.EmpNo equals vh.EmpNo 
       join rl in context.EmployeeAccessLevels on ea.RoleID equals rl.id into outer_join 
       from subjoin in outer_join 

       //need code to join all data according to EmpNo's GroupIDs 

       group new 
       { 
        ea.EmpNo, 
        subjoin.Role, 
        vh.EmailAddress, 
        vh.LNameByFName, 
        ea.Active 

       } by vh.LNameByFName into grp 
       let item = grp.FirstOrDefault() 
       orderby item.Role ascending 
       select new EmployeeWithEmail 
       { 
        EmpNum = item.EmpNo ?? 0, 
        Role = item.Role, 
        EmailAddress = item.EmailAddress, 
        LNameByFname = item.LNameByFName, 
        Active2 = item.Active ?? false 

       }).ToList(); 

    } 
} 

我想我想篩選兩次,並加入普通的數據,但實際上有兩個過濾器,我不知道如何控制。

所以我的輸出會是這樣:

EmpNo ---> __ 01 | 01 | 01 | 01 

GroupID ---> __10 | 10 | 20 | 20 

Data ---> _________Apple | Apple | Orange | Orange 

我可以過濾EMPNO 01和10組ID,但如果在EMPNO屬於兩個組? 對不起,找不到正確的術語。

在此先感謝。

+0

你能寫出一個T-SQL語句來給你想要的嗎?如果是這樣,那會是什麼? (這將幫助我更好地理解你在做什麼之後) – David

+0

我在LINQ中純粹編碼,因爲我對它非常陌生,尤其是SQL。但無論如何,我會立即想出一個看法。 –

+0

SELECT dbo.EmployeeAccess.EmpNo,dbo.View_SystemAdminMembers.LNameByFName AS表達式1,dbo.View_SystemAdminMembers.GroupName AS EXPR2, dbo.View_SystemAdminMembers.Role AS表達式3,dbo.View_SystemAdminMembers.Active,dbo.View_SystemAdminMembers.EmpNo AS Expr4, DBO。 View_SystemAdminMembers.RoleID FROM dbo.EmployeeAccess INNER JOIN dbo.View_SystemAdminMembers ON dbo.EmployeeAccess.GroupID = dbo.View_SystemAdminMembers.GroupID WHERE(dbo.EmployeeAccess.EmpNo = '01') –

回答

2

基於您的評論,您要產生應該是SQL(我已經略微簡化的)

SELECT EmployeeAccess.EmpNo, View_SystemAdminMembers.LNameByFName, View_SystemAdminMembers.GroupName, 
     View_SystemAdminMembers.Role, View_SystemAdminMembers.Active, View_SystemAdminMembers.EmpNo, 
     View_SystemAdminMembers.RoleID 
FROM EmployeeAccess 
    INNER JOIN View_SystemAdminMembers ON EmployeeAccess.GroupID = View_SystemAdminMembers.GroupID 
WHERE (EmployeeAccess.EmpNo = '01') 

這是你展示你的問題是什麼很不同:

from ea in context.View_SystemAdminMembers 
    join vh in context.View_HCM on (Int16)ea.EmpNo equals vh.EmpNo 
    join rl in context.EmployeeAccessLevels on ea.RoleID equals rl.id into outer_join 
    from subjoin in outer_join 

所以我不確定我的答案是否會有所幫助,但要獲得您指定的SQL,我認爲您應該這樣做:

var query = 
from ea in context.EmployeeAccess 
join vsam in context.View_SystemAdminMembers on ea.GroupID equals vsam.GroupID 
where ea.EmpNo == "01" 
select new 
{ 
    ea.EmpNo, vsam.LNameByFName, vsam.GroupName, vsam.Role, vsam.Active, vsam.EmpNo, vsam.RoleID 
}; 

用流利的語法(未查詢語法),它看起來有點像:

var query = 
    context.EmployeeAccess 
    .Join(context.View_SystemAdminMembers, allEA => allEA.GroupID, allVSAM => allVSAM.GroupID, (ea, vsam) => new {ea, vsam}) 
    .Where(combined => combined.ea.EmpNo == "01") 
    .Select(combined => combined.ea.EmpNo, combined.vsam.LNameByFName, combined.vsam.GroupName, combined.vsam.Role, combined.vsam.Active, combined.vsam.EmpNo, combined.vsam.RoleID); 

(雖然我承認 - 我正常返回整個實體像 .Select(combined => combined.ea)或類似的東西,所以我不是100%某些在最後一行......)

請注意,在這兩種情況下,「var query」將是IQueryable,這意味着您仍需要添加ToList或等效項才能獲得結果。但是,在你做這件事之前,你需要應用Tim Burkhart的回答,對其進行任何修改(如GroupBy或其他)。正如他所指出的,關於IQueryable的一件很酷的事情是,你不必在一個聲明中這樣做;你可以採取query正如我上面所定義,然後添加類似

query = query.Where(c => c.LNameByFName.Contains("A")) 

或什麼的。

還有一點需要注意 - 您的返回值完全由View_SystemAdminMembers中的項目組成,但EmployeeAccess.EmpNo除外,但由於您正在對此進行過濾,因此您應該已經知道它是什麼。只返回一個View_SystemAdminMember對象可能更容易,而不是創建一個新類型。這取決於你。

2

我並不真正關注你所要求的。也許它可以改寫或給予更多的上下文或格式不同?

但我想我會提出一些建議,可以幫助你到達你想去的地方。

1 - 函數名稱意味着該人員將提供一封電子郵件並接收包含該電子郵件的多個Employee對象。但它似乎接受一個員工id並返回一個EmployeeWithEmail列表。考慮重命名該函數以匹配它正在做的事情。還考慮返回IEnumerable<Employee>IEnumerable<IEmployeeEmailView>

2 - 此功能做了很多。 (並且需要花費幾秒鐘的時間來弄清楚它在做什麼)。在這樣的情況下,我會從簡單的開始。不要做分組或排序等任何事情。有一些函數返回的這個結果:

from ea in context.View_SystemAdminMembers 
join vh in context.View_HCM on (Int16)ea.EmpNo equals vh.EmpNo 
join rl in context.EmployeeAccessLevels on ea.RoleID equals rl.id into outer_join 
from subjoin in outer_join 
中的一些形式

IEnumerable<Employee>

public class Employee { 
    public int Id { get; set; } 
    public string Role { get; set; } 
    public string EmailAddress { get; set; } 
    public string Name { get; set; } 
    public bool IsActive { get; set; } 
} 

從那裏,事情更容易對付。您不必使用LINQ到SQL。你可以做...

IEnumerable<Employee> employees = <your renamed function>(); 
var employeesGroupedByName = employees.GroupBy(e => e.Name); 

希望這可以讓你更容易。它不能解決你的答案,但我認爲它可能使事情變得簡單/容易。

所以寫出來完全,它可能是這樣的:

public class EmployeeRepository { 
    public IEnumerable<Employee> GetAll() { 
     // This function won't compile. I don't know the syntax for this type of LINQ 
     using (var context = new SQL_TA_SCOREBOARDEntities1()) { 
      return (from ea in context.View_SystemAdminMembers 
      join vh in context.View_HCM on (Int16)ea.EmpNo 
      join rl in context.EmployeeAccessLevels on ea.RoleID equals rl.id into outer_join 
     } 
    } 

    public IEnumerable<Employee> GetAllEmployeesWithEmployeeId(int employeeId) { 
     return GetAll().Where(e => e.Id == employeeId).ToList(); 
    } 

    public IEnumerable<Employee> SomeOtherFunctionThatDoesWhatYouWantToDoFromThisPost() { 
     // You could also create a class that extends IEnumerable<Employee> to 
     // encapsulate the logic so that the repository doesn't have a million functions 
    } 
} 

這就是我的一切給你。如果問題更好一點,我可以給出更完整的答案,但希望這能讓你走上正確的軌道。

+0

感謝您的,是的,我已經聲明瞭一個類比如你的。另外,我害怕使用lambda,因爲我沒有完全理解它。但好吧,我會盡我所能來解決你的代碼! –

+1

你應該瞭解lambda。它們非常易於使用,它們非常強大。他們也允許鏈接過濾。 –