具有多个 LEFT JOIN 的 LINQ 查询
LINQ query with multiple LEFT JOIN
我有 1 个主 table 和 3 个 table 用于对主 table 中的字段进行排序。我 return 所有这些 table 作为列表。
主要的table结构是这样的:
Color
Make
Country
Black
Mercedes
Germany
Blue
Mercedes
Germany
Cyan
Mercedes
Germany
Red
Mercedes
Germany
Blue
BMW
Germany
Red
BMW
Germany
Blue
Toyota
Japan
Purple
Mercedes
Germany
而订购 table 在主 table 中有字段名称,还有另一个数字字段作为订购编号,例如:
Color
ColorOrder
Black
6
Blue
2
Cyan
3
Red
4
现在我想根据 Ordering Tables in LINQ 中的排序数字来排序 Main table。如果主table如果排序中没有相应的字段table那么排序编号应该是0(在ColorOrdering中没有Purple例如)
为了具体起见,我在 Access 和 Query 中制作了一个工作示例,如下所示:
SELECT Cars.Color, Cars.Make, Cars.Country,
IIf([MakeOrder] Is Null,0,[MakeOrder]) AS MkOrder,
IIf([ColorOrder] Is Null,0,[ColorOrder]) AS ClOrder,
IIf([CountryOrder] Is Null,0,[CountryOrder]) AS CntOrder
FROM ((Cars LEFT JOIN ColorOrder ON Cars.Color = ColorOrder.Color)
LEFT JOIN MakeOrder ON Cars.Make = MakeOrder.Make)
LEFT JOIN CountryOrder ON Cars.Country = CountryOrder.Country
ORDER BY
IIf([MakeOrder] Is Null,0,[MakeOrder]),
IIf([ColorOrder] Is Null,0,[ColorOrder]),
IIf([CountryOrder] Is Null,0,[CountryOrder]);
我的问题之一是订购 table 没有记录(国家/地区 Table)。所以当我连接到 table 时,无论我做什么,我都会得到
System.NullReferenceException: 'Object reference not set to an instance of an object.' cntord was null.
这是我的 LINQ 查询,非常感谢您的帮助。
List<CarsWithOrdering> carsWithOrdering = (from c in Cars
//Also tried this, doesn't work
//join cntord in CountryOrderingList.DefaultIfEmpty()
// on c.Country equals cntord.Country
join cntord in CountryOrderingList
on c.Country equals cntord.Country into lcntord
from cntord in lcntord.DefaultIfEmpty()
//........ (Other 2 left joins similar to above one)
select new CarsWithOrdering
{
Color = c.Color,
Make = c.Make,
Country = c.Country,
ColorOrder = int.Parse(colord.ItemValue) ?? 0,
MakeOrder = int.Parse(makord.ItemValue) ?? 0,
CountryOrder = int.Parse(cntord.ItemValue) ?? 0
}).ToList();
Enumerable.DefaultIfEmpty
Method
public static System.Collections.Generic.IEnumerable<TSource> DefaultIfEmpty<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, TSource defaultValue);
Returns
IEnumerable An IEnumerable that contains defaultValue if source is empty; otherwise, source.
当列表为空时,.DefaultIfEmpty()
将 return null
。
解决方案
因此,您需要在访问其属性之前null
检查 LEFT JOIN table 的值。
List<CarsWithOrdering> carsWithOrdering = (from c in Cars
join cntord in CountryOrderingList
on c.Country equals cntord.Country into lcntord
from cntord in lcntord.DefaultIfEmpty()
//Other LEFT JOIN tables
select new CarsWithOrdering
{
Color = c.Color,
Make = c.Make,
Country = c.Country,
ColorOrder = colord != null ? int.Parse(colord.ItemValue) : 0,
MakeOrder = makord != null ? int.Parse(makord.ItemValue) : 0,
CountryOrder = cntord != null ? int.Parse(cntord.ItemValue) : 0
})
.ToList();
我有 1 个主 table 和 3 个 table 用于对主 table 中的字段进行排序。我 return 所有这些 table 作为列表。
主要的table结构是这样的:
Color | Make | Country |
---|---|---|
Black | Mercedes | Germany |
Blue | Mercedes | Germany |
Cyan | Mercedes | Germany |
Red | Mercedes | Germany |
Blue | BMW | Germany |
Red | BMW | Germany |
Blue | Toyota | Japan |
Purple | Mercedes | Germany |
而订购 table 在主 table 中有字段名称,还有另一个数字字段作为订购编号,例如:
Color | ColorOrder |
---|---|
Black | 6 |
Blue | 2 |
Cyan | 3 |
Red | 4 |
现在我想根据 Ordering Tables in LINQ 中的排序数字来排序 Main table。如果主table如果排序中没有相应的字段table那么排序编号应该是0(在ColorOrdering中没有Purple例如)
为了具体起见,我在 Access 和 Query 中制作了一个工作示例,如下所示:
SELECT Cars.Color, Cars.Make, Cars.Country,
IIf([MakeOrder] Is Null,0,[MakeOrder]) AS MkOrder,
IIf([ColorOrder] Is Null,0,[ColorOrder]) AS ClOrder,
IIf([CountryOrder] Is Null,0,[CountryOrder]) AS CntOrder
FROM ((Cars LEFT JOIN ColorOrder ON Cars.Color = ColorOrder.Color)
LEFT JOIN MakeOrder ON Cars.Make = MakeOrder.Make)
LEFT JOIN CountryOrder ON Cars.Country = CountryOrder.Country
ORDER BY
IIf([MakeOrder] Is Null,0,[MakeOrder]),
IIf([ColorOrder] Is Null,0,[ColorOrder]),
IIf([CountryOrder] Is Null,0,[CountryOrder]);
我的问题之一是订购 table 没有记录(国家/地区 Table)。所以当我连接到 table 时,无论我做什么,我都会得到
System.NullReferenceException: 'Object reference not set to an instance of an object.' cntord was null.
这是我的 LINQ 查询,非常感谢您的帮助。
List<CarsWithOrdering> carsWithOrdering = (from c in Cars
//Also tried this, doesn't work
//join cntord in CountryOrderingList.DefaultIfEmpty()
// on c.Country equals cntord.Country
join cntord in CountryOrderingList
on c.Country equals cntord.Country into lcntord
from cntord in lcntord.DefaultIfEmpty()
//........ (Other 2 left joins similar to above one)
select new CarsWithOrdering
{
Color = c.Color,
Make = c.Make,
Country = c.Country,
ColorOrder = int.Parse(colord.ItemValue) ?? 0,
MakeOrder = int.Parse(makord.ItemValue) ?? 0,
CountryOrder = int.Parse(cntord.ItemValue) ?? 0
}).ToList();
Enumerable.DefaultIfEmpty
Method
public static System.Collections.Generic.IEnumerable<TSource> DefaultIfEmpty<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, TSource defaultValue);
当列表为空时,Returns
IEnumerable An IEnumerable that contains defaultValue if source is empty; otherwise, source.
.DefaultIfEmpty()
将 return null
。
解决方案
因此,您需要在访问其属性之前null
检查 LEFT JOIN table 的值。
List<CarsWithOrdering> carsWithOrdering = (from c in Cars
join cntord in CountryOrderingList
on c.Country equals cntord.Country into lcntord
from cntord in lcntord.DefaultIfEmpty()
//Other LEFT JOIN tables
select new CarsWithOrdering
{
Color = c.Color,
Make = c.Make,
Country = c.Country,
ColorOrder = colord != null ? int.Parse(colord.ItemValue) : 0,
MakeOrder = makord != null ? int.Parse(makord.ItemValue) : 0,
CountryOrder = cntord != null ? int.Parse(cntord.ItemValue) : 0
})
.ToList();