Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq中的多个左连接和组合等于和不等于_C#_Linq_Linq To Dataset - Fatal编程技术网

C# Linq中的多个左连接和组合等于和不等于

C# Linq中的多个左连接和组合等于和不等于,c#,linq,linq-to-dataset,C#,Linq,Linq To Dataset,我正在尝试连接两个数据表,以便在CustID列上将第一个表左键连接到第二个表两次。联接中的第一个plant表必须与动物表中的PlantID匹配,第二个plant表不得与动物表中的PlantID匹配。然而,当我在Linq中尝试这一点时,它似乎完全忽略了where子句 动物: ID | CustID | PlantID ===================== 1 | 1 | <null> 2 | 2 | 1 3 | 2 | <null&

我正在尝试连接两个数据表,以便在CustID列上将第一个表左键连接到第二个表两次。联接中的第一个plant表必须与动物表中的PlantID匹配,第二个plant表不得与动物表中的PlantID匹配。然而,当我在Linq中尝试这一点时,它似乎完全忽略了where子句

动物:

ID | CustID | PlantID
=====================
1  |   1    | <null>
2  |   2    |    1
3  |   2    | <null>
在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 to数据集进行尝试时的代码:

        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();
当我尝试使用linq to对象时,第二行不存在,这是我所期望的。以下是我使用对象的代码:

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

我知道我做错了什么。My where子句用于比较匿名类型的字段,这些字段通过引用进行比较。where子句应该是

Where(st => !st.plantid1.Equals(st.plantid2))
比较这些字段的值

    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(st => !st.plantid1.Equals(st.plantid2))