在defaultifempty中,在linq错误中左外连接

时间:2015-03-14 20:09:08

标签: c# linq

所以我有3张桌子 我想在所有3上做左外连接但是说

表1有

id   name
1    peter
2    john

表2有

id address
1   123 ave 
2   456 blvd

表3有

table1id table2id
1           1
1           2
2           1 
2           2

表3是表1和2的外部参照

所以,如果我在表1中添加一条记录,当我按名称搜索时,我需要获取该名称所关联的名称和地址,但它没有返回任何内容,因为我还没有在表3中插入任何内容。所以我试图做左连接,但我遇到了错误

var query = from t1 in table1 
            join t3 in table3 on t1.id equals t3.table1id into leftt1 
            from l1 in leftt1.defaultifempty() 
            join t2 in table2 on l1.table2id equals t2.id 
            select.......

错误是defaultifempty。它实际上返回空而不是我刚刚添加的新记录。我的左外连接有什么问题吗?请帮忙。谢谢

3 个答案:

答案 0 :(得分:0)

感谢您的澄清。

假设问题描述,我认为您需要使用INNER JOIN而不是LEFT JOIN,因为第3个表存储第1和第2个表中的数据。

参见示例(使用LinqPad):

DataTable dt1 = new DataTable();
DataColumn dc = new DataColumn("id", System.Type.GetType("System.Int32"));
dt1.Columns.Add(dc);
dc = new DataColumn("name", System.Type.GetType("System.String"));
dt1.Columns.Add(dc);
dt1.Rows.Add(new Object[]{1, "Peter"});
dt1.Rows.Add(new Object[]{2, "John"});


DataTable dt2 = new DataTable();
dc = new DataColumn("id", System.Type.GetType("System.Int32"));
dt2.Columns.Add(dc);
dc = new DataColumn("address", System.Type.GetType("System.String"));
dt2.Columns.Add(dc);
dt2.Rows.Add(new Object[]{1, "123 ave"});
dt2.Rows.Add(new Object[]{2, "456 blvd"});

DataTable dt3 = new DataTable();
dc = new DataColumn("id1", System.Type.GetType("System.Int32"));
dt3.Columns.Add(dc);
dc = new DataColumn("id2", System.Type.GetType("System.Int32"));
dt3.Columns.Add(dc);
dt3.Rows.Add(new Object[]{1, 1});
dt3.Rows.Add(new Object[]{1, 2});
dt3.Rows.Add(new Object[]{2, 1});
dt3.Rows.Add(new Object[]{2, 2});

var qry = from refdata in dt3.AsEnumerable()
        join userdata in dt1.AsEnumerable() on refdata.Field<int>("id1") equals userdata.Field<int>("id")
        join addressdata in dt2.AsEnumerable() on refdata.Field<int>("id2") equals addressdata.Field<int>("id")
        select new
        {
            uid = userdata.Field<int>("id"),
            uname = userdata.Field<string>("name"),
            aid = addressdata.Field<int>("id"),
            aadress = addressdata.Field<string>("address")
        };

结果:

uid    uname    aid   aadress
1      Peter    1     123 ave 
1      Peter    2     456 blvd 
2      John     1     123 ave 
2      John     2     456 blvd 

答案 1 :(得分:0)

我最终不得不像这样

之后重新定义我的结构
var query = from t1 in table1 
        join t3 in table3 on t1.id equals t3.table1id into leftt1 
        from l1 in leftt1.defaultifempty(new t3 {table1id=table1id.id, table2id=0}) 
        join t2 in table2 on l1.table2id equals t2.id 
        select.......

你也可以为其他人做同样的事情。它现在正在运作。感谢

答案 2 :(得分:0)

你可以这样做:

var query = from t1 in table1s 
            join t3 in table3s on t1.Id equals t3.table1Id 
                into left1
            from l1 in left1.DefaultIfEmpty()
            join t2 in table2s on (l1 == null ? -1 : l1.table2Id) equals t2.Id
                into left2
            from l2 in left2.DefaultIfEmpty()
            select new { t1, l2 };

因此,您不需要虚拟t3实例来跨越外部联接间隙。