[英]Multiple left joins and combining equals and not equals in Linq
我試圖聯接兩個DataTable,以使第一個表在CustID列上兩次左聯接到第二個表。 第一個植物表必須與動物表中的PlantID匹配,並且聯接中的第二個植物表必須與動物表中的PlantID不匹配。 但是,當我在Linq中嘗試此操作時,它似乎完全忽略了where子句。
動物:
ID | CustID | PlantID
=====================
1 | 1 | <null>
2 | 2 | 1
3 | 2 | <null>
植物:
ID | CustID | Name
==================
1 | 2 | b1
2 | 2 | b2
在SQL中,我想要的查詢將是:
SELECT a.id, a.custid, p1.id AS PlantID1, p2.id AS PlantID2
FROM animals a
LEFT JOIN plants p1 on a.custid = p1.custid AND a.plantid = p1.id
LEFT JOIN plants p2 on a.custid = p2.custid AND a.plantid != p2.id
這是我使用linq嘗試到數據集時的代碼:
DataTable animals = new DataTable();
animals.Columns.Add("id", typeof(int));
animals.Columns.Add("custid", typeof(int));
animals.Columns.Add("plantid", typeof(int));
animals.Rows.Add(1, 1, DBNull.Value);
animals.Rows.Add(2, 2, 1);
animals.Rows.Add(3, 2, DBNull.Value);
DataTable plants = new DataTable();
plants.Columns.Add("id", typeof(int));
plants.Columns.Add("custid", typeof(int));
plants.Columns.Add("name", typeof(string));
plants.Rows.Add(1, 2, "b1");
plants.Rows.Add(2, 2, "b2");
var test = from al in animals.AsEnumerable()
join bl in plants.AsEnumerable()
on new { x = al["custid"], y = al["plantid"] } equals new { x = bl["custid"], y = bl["id"] } into gj
join bl2 in plants.AsEnumerable()
on al["custid"] equals bl2["custid"] into gj2
from subbl in gj.DefaultIfEmpty()
from subbl2 in gj2.DefaultIfEmpty()
select new
{
aid = al["id"],
custid = al["custid"],
plantid1 = subbl == null ? DBNull.Value : subbl["id"],
plantName = subbl == null ? DBNull.Value : subbl["name"],
plantid2 = subbl2 == null ? DBNull.Value : subbl2["id"],
plantName2 = subbl2 == null ? DBNull.Value : subbl2["name"]
};
var result = test.Where(st => st.plantid1 != st.plantid2).Cast<object>().ToList();
我得到的結果包括以下行,我認為該行將被Where子句排除:
aid | custid | plantid1 | plantid2
==================================
1 | 1 |
2 | 2 | 1 | 1
2 | 2 | 1 | 2
2 | 2 | | 1
2 | 2 | | 2
當我對對象使用linq進行嘗試時,第二行不存在,這是我期望的。 這是我使用對象的代碼:
class animal
{
public int id, custid;
public int? plantid;
}
class plant
{
public int id;
public int custid;
public string name;
}
List<object> testStructs()
{
List<animal> animals = new List<animal>()
{
new animal() { id = 1, custid = 1, plantid = 0 },
new animal() { id = 2, custid = 2, plantid = 1 },
new animal() { id = 3, custid = 2 }
};
List<plant> plants = new List<plant>()
{
new plant() { id = 1, custid = 2, name = "col1" },
new plant() { id = 2, custid = 2, name = "col2" }
};
var test = from al in animals.AsEnumerable()
join bl in plants.AsEnumerable()
on new { x = al.custid, y = al.plantid } equals new { x = bl.custid, y = (int?)bl.id } into gj
join bl2 in plants.AsEnumerable()
on al.custid equals bl2.custid into gj2
from subbl in gj.DefaultIfEmpty()
from subbl2 in gj2.DefaultIfEmpty()
select new
{
aid = al.id,
custid = al.custid,
plantid1 = subbl == null ? null : (int?)subbl.id,
plantName = subbl == null ? string.Empty : subbl.name,
plantid2 = subbl2 == null ? null : (int?)subbl2.id,
plantName2 = subbl2 == null ? string.Empty : subbl2.name
};
return test.Where(st => st.plantid1 != st.plantid2 || st.plantid1 == null || st.plantid2 == null).Cast<object>().ToList();
}
我弄清楚我做錯了什么。 我的where子句正在比較匿名類型的字段,這些字段通過引用進行比較。 where子句應該是
Where(st => !st.plantid1.Equals(st.plantid2))
比較這些字段的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.