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

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

我有两个 table:

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 table.

中搜索 studentid

我已经为你准备了一份fiddle - 如果有任何问题,请随时提出。

顺便说一句:这个解决方案解决了你的问题。 data-structure 本身很丑,应该规范化。

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

你可以使用LINQJoin方法来实现你想要的:

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 Table 设计,这违反了 SQL Normalization Forms(特别是第一范式),说那:

Each sell should be single-valued.

这意味着您不应在 table 列中使用逗号(或任何其他字符)分隔值。

要使上述查询有效,您必须使 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,表示:

All Attributes (non-key columns) should be dependent on a Key.

4th Normal form,表示:

There should be no multi-value dependencies (Rose ⟶ 1, Rose ⟶ 12)

正确的解决方案是为 Student⟶Conference 关系创建另一个 table。

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 模型。

通过使用相同的 Navigation Properties(如果您正确定义了 EF 关系),您可以获得更简单的版本:

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

更新二:

我不想这么说,但如果您无法更改数据库设计,则有一种解决方法:

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

注意:从应用程序性能的角度来看,这不会有效。

与上述相比更好的替代方法是编写 Stored Procedure 并从 EF 调用它。