2011-02-04 78 views
2

我對linq很新,所以請耐心等待。如何使用LINQ-to-SQL連接多個表?

我正在研究一個asp.net網頁,我想添加一個「搜索功能」(用戶輸入姓名或姓氏或兩者或只是其部分的文本框,並獲取所有相關信息)。我有兩個表格(「Person」和「Application」),我想顯示Person(姓名和姓氏)以及一些來自Application(score,position,...)的一些列。我知道如何使用sql做到這一點,但我想了解更多關於linq的知識,因此我想用linq來做。

現在我有兩個主要思路:

1)

var person = dataContext.GetTable<Person>(); 
    var application = dataContext.GetTable<Application>(); 
    var p1 = from p in Person 
      where(p.Name.Contains(tokens[0]) || p.Surname.Contains(tokens[1])) 
      select new {Id = p.Id, Name = p.Name, Surname = p.Surname}; //or maybe without this line 

//I don't know how to do the following properly 
var result = from a in Application 
       where a.FK_Application.Equals(index) //just to get the "right" type of application 
       //this is not right, but I don't know how to do it better 
       join p1 
       on p1.Id == a.FK_Person 

2)另一種想法就是要經過「申請」和而不是「加入P1 ......」使用

var result = from a in Application 
      where a.FK_Application.Equals(index) //just to get the "right" type of application 
      join p from Person 
      on p.Id == a.FK_Person 
      where p.Name.Contains(tokens[0]) || p.Surname.Contains(tokens[1])  

我認爲,第一個想法是查詢,而第一個「地方」的條件,這也是我打算用更好。無論什麼更好(更快),我仍然不知道如何使用linq來做到這一點。最後,我想顯示/選擇結果的一些部分(列)(連接表格+過濾條件)。

我真的很想知道如何使用linq做這樣的事情,因爲我將處理一些類似的本地數據問題,我只能使用linq。 有人可以請我解釋一下怎麼做,我花了好幾天的時間試圖找出答案並在網上搜索。

+0

那麼,這是Linq-to-SQL? – 2011-02-04 14:45:24

+0

是的,這是Linq-to-SQl(在C#中,Framework 4.0)。我完全忘了提及它。 – Ben 2011-02-04 16:46:43

回答

3
var result = from a in dataContext.Applications 
      join p in dataContext.Persons 
      on p.Id equals a.FK_Person 
      where (p.Name.Contains("blah") || p.Surname.Contains("foo")) && a.FK_Application == index 
      select new { Id = p.Id, Name = p.Name, Surname = p.Surname, a.Score, a.Position }; 

好視Odrahn指出,這會給你平坦的結果,與一個人可能很多行,因爲一個人可以加入多個應用程序都具有相同的FK。這裏有一個方法來搜索所有合適的人,然後對相關應用程序添加到的結果:

var p1 = from p in dataContext.Persons 
      where(p.Name.Contains(tokens[0]) || p.Surname.Contains(tokens[1])) 
      select new { 
       Id = p.Id, Name = p.Name, Surname = p.Surname, 
       BestApplication = dataContext.Applications.FirstOrDefault(a => a.FK_Application == index /* && ???? */); 
     }; 

對不起 - 它看起來像第二個查詢將導致每人往返,因此它顯然不會可擴展。我認爲L2S會更好地處理它。

+0

謝謝,這正是我所需要的。你能幫我解決如何啓用排序。我將結果綁定到gridview。我必須提供自己的排序方法,我曾考慮過使用「result.OrderBy ...」,但結果對其他方法是本地的,我無法使其成爲全局的,因爲它是「var」,我試着做一個特殊的類並將結果聲明爲全局:「IQueryable 結果;」但後來我不知道如何將結果從上面的代碼轉換爲「IQueryable 結果」。感謝您的時間和幫助。 – Ben 2011-02-04 20:12:53

1

爲了正確回答這個問題,我需要知道應用程序和人員是否直接相關(即人員是否有很多應用程序)?從閱讀你的文章,我假設他們是因爲應用程序似乎有一個外鍵的人。

如果是這樣,那麼你可以創建一個自定義PersonModel將由字段填入您從不同的實體需要這樣的:

class PersonModel 
{ 
    string Name { get; set; } 
    string Surname { get; set; } 
    List<int> Scores { get; set; } 
    List<int> Positions { get; set; } 
} 

然後填充它,你會做以下幾點:

// Select the correct person based on Name and Surname inputs 
var person = dataContext.Persons.Where(p => p.Name.Contains("firstname") || p.Name.Contains("surname")).FirstOrDefault(); 
// Get the first person we find (note, there may be many - do you need to account for this?) 

if (person != null) 
{ 
    var scores = new List<int>(); 
    var positions = new List<int>(); 

    scores.AddRange(person.Applications.Select(i => i.Score); 
    positions.AddRange(person.Applications.Select(i => i.Position); 

    var personModel = new PersonModel 
          { 
           Name = person.Name, 
           Surname = person.Surname, 
           Scores = scores, 
           Positions = positions 
          }; 
} 

由於人與應用程序之間的關係,如果一個人可以有很多應用程序,我必須說明存在許多分數和位置(因此列表)的可能性。

另外請注意,我已經使用lambda表達式而不是普通的linqToSql進行簡單選擇,以便您可以輕鬆查看發生了什麼。