如何使用具有某些 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 调用它。
我有两个 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 调用它。