[英]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 ⟶ 1
,Rose ⟶ 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.