簡體   English   中英

如何使用具有某些 ID 的一列加入或搜索 Id

[英]How to Join or search Id with one column which have some Id

我有兩張桌子:

Student         Conference
+----+------+   +----+-------+---------------+
| id | name |   | id | name  | ref_studentId |
+----+------+   +----+-------+---------------+
|  1 | jack |   |  1 | Rose  | 1,12          |
|  2 | kai  |   |  2 | White | 12            |
|  3 | wind |   |  3 | Black | 1,12,12356    |
+----+------+   +----+-------+---------------+

我想將他們與studentid一起加入或在conference桌中搜索studentid

我已經為你准備了一個小提琴 - 如果有任何問題,請隨時提出。

順便說一句:這個解決方案解決了你的問題。 數據結構本身很難看,應該規范化。

void Main()
{
    var students = new List<Student>
    {
        new Student { Id = 1, Name = "jack" },
        new Student { Id = 12, Name = "kai" },
        new Student { Id = 12356, Name = "wind" }
    };
    
    var conferences = new List<Conference>
    {
        new Conference { Id = 1, Name = "Rose", RefIds = "1,12" },
        new Conference { Id = 2, Name = "White", RefIds = "12" },
        new Conference { Id = 25, Name = "Black", RefIds = "1,12,12356" }
    };
    
    var result = students.Select(s => new Tuple<int, Conference[]>(s.Id, conferences.Where(c => c.RefIds.Split(",").Contains(s.Id.ToString())).ToArray()));
}

// Define other methods, classes and namespaces here
public class Student
{
    public int Id {get; set;}
    public string Name {get;set;}
}

public class Conference
{
    public int Id {get; set;}
    public string Name {get; set;}
    public string RefIds {get; set;}
}

您可以使用 LINQ Join方法來實現您想要的:

var result = dataContext.Students.Join(dataContext.Conferences,
                                     st => st.id, 
                                     cf => cf.ref_studentId, 
                                     (student, conference) => new { ... });

盡管我強烈建議使用 Entity Framework Navigation Properties ,但使用它可以更輕松地完成上述操作:

var result = dataContext.Student.Include(st => st.conference);

更新:

請注意,上面的 LINQ 查詢將無法執行,除非您修復您的Conference表設計,這是針對SQL 規范化 Forms (特別是第一范式)的,說:

每次銷售都應該是單值的。

這意味着您的表格列中不應有逗號(或任何其他字符)分隔值。

要使上述查詢有效,您必須使ref_studentId僅包含StudentId的單個值:

Conference
+----+--------+-----------+
| ID |  Name  | StudentId |
+----+--------+-----------+
|  1 | Rose   |         1 |
|  2 | Rose   |        12 |
|  3 | White  |        12 |
|  4 | Black  |         1 |
|  5 | Black  |        12 |
|  6 | Black  |     12356 |
+----+--------+-----------+

但老實說,這個也不符合 SQL 規范化規則。
具體來說, 2nd Normal Form說:

所有屬性(非鍵列)都應依賴於鍵。

第四范式,說:

不應存在多值依賴項( Rose ⟶ 1Rose ⟶ 12

正確的解決方案是為 Student⟶Conference 關系創建另一個表。

Conference        ConferencesStudents
+----+-------+    +----+--------------+-----------+ 
| ID | Name  |    | ID | ConferenceID | StudentId |
+----+-------+    +----+--------------+-----------+
|  1 | Rose  |    |  1 |            1 |         1 |
|  2 | White |    |  2 |            1 |        12 |
|  3 | Black |    |  3 |            2 |        12 |
+----+-------+    |  4 |            3 |         1 |
                  |  5 |            3 |        12 |
                  |  6 |            3 |     12356 |
                  +----+--------------+-----------+

現在,對於這個 LINQ 查詢將是:

dataContext.ConferencesStudents.Join(dataContext.Students,
        cf => cf.ConferenceID,
        st => st.ID,
        (conferencesStudents, student) => new { conferencesStudents, student })
    .Join(dataContext.Conferences,
        cfSt => cfSt.conferencesStudents.ConferenceID,
        cf => cf.ID, 
        (cfSt, conference) =>
        new
        {
            Student = cfSt.student,
            Conference = conference
        });

注意:對於上面的內容,我使用匿名類型只是為了演示,我的強烈建議是使用真實的 class 模型。

要么

通過使用相同的導航屬性(如果您正確定義了 EF 關系),您可以獲得一個更簡單的版本:

dataContext.ConferenceStudents.Include(cf => cf.Conferences)
                              .Include(cf => cf.Students)

更新 2:

我不想這么說,但如果您無法更改數據庫設計,則有一種解決方法:

var results = (
    from c in dataContext.Conference.ToList() // populating all Conferences
    from s in dataContext.Students.ToList()   // populating all Students
    where c.ref_studentId.Split(',').Contains(s.id.ToString())
    select new
    {
        Student = s,
        Conference = c
    }).ToList();

注意:從應用程序性能的角度來看,這不會有效。

與上述相比更好的替代方案可能是編寫存儲過程並從 EF 調用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM