假设我们有以下表格:
CAR
ID Name
1 Mustang
2 Taurus
CAR_PART
ID CAR_ID PART_NUMBER
1 1 M772
2 1 A443
3 2 Z889
CAR_COLOR
ID CAR_ID COLOR_NAME
1 1 Red
2 1 Blue
3 2 Yellow
我们需要使用Linq-to-SQL来获得以下结果:
CAR_ID CAR_NAME CAR_PART_LIST CAR_COLOR_LIST
1 Mustang M772,A443 Red,Blue
这将如何实现?我用结果列名称创建了一个新类,并在末尾添加了一个select new MyClass{};
,但不确定如何处理CAR_PART_LIST
和CAR_COLOR_LIST
的多个分组列。
有什么想法吗?
编辑:这是我到目前为止的内容:
from car in db.CAR
join part in db.CAR_PART on car.ID equals part.CAR_ID
join color in db.CAR_COLOR on car.ID equals color.CAR_ID
where car.ID = 1
select new MySearchResult{
CAR_ID = car.ID,
CAR_NAME = car.Name,
CAR_PART_LIST = ?,
CAR_COLOR_LIST = ?
}
public class MySearchResult{
public int CAR_ID { get; set; }
public string CAR_NAME { get; set; }
public string CAR_PART_LIST { get; set; }
public string CAR_COLOR_LIST { get; set; }
public MySearchResult() { }
}
答案 0 :(得分:1)
使用明显的String
扩展方法:
public static string Join(this IEnumerable<string> s, string sep) => String.Join(s, sep);
您可以通过在每个相关表上使用组联接来计算答案:
var ans = from car in db.CAR
join part in db.CAR_PART on car.ID equals part.CAR_ID into partj
join color in db.CAR_COLOR on car.ID equals color.CAR_ID into colorj
where car.ID == 1
select new MySearchResult {
CAR_ID = car.ID,
CAR_NAME = car.Name,
CAR_PART_LIST = partj.Select(p => p.PART_NUMBER).Join(","),
CAR_COLOR_LIST = colorj.Select(c => c.COLOR_NAME).Join(",")
};
答案 1 :(得分:1)
您是否为db.CAR_PART和db.CAR_COLOR设置了外键?如果是这样,该linq-to-sql将自动为您提供联接的属性。因此,它变为:
var q = from car in db.Car
where car.ID == 1
select new MySearchResult
{
CAR_ID = car.ID,
CAR_NAME = car.Name,
CAR_PART_LIST = String.Join(",", car.CAR_PARTs.Select(cp=>cp.PART_NUMBER))
CAR_PART_LIST = String.Join(",", car.CAR_COLORs.Select(cp=>cp.COLOR_NAME))
};
答案 2 :(得分:1)
我在这里{{3}}上写下了它,请查看:
var q = from car in cars
join part in carparts on car.ID equals part.CAR_ID into parts
join color in carcolors on car.ID equals color.CAR_ID into clrs
where car.ID == 1
select new MySearchResult{
CAR_ID = car.ID,
CAR_NAME = car.Name,
CAR_PART_LIST = String.Join(",",parts.Select(p => p.PART_NUMBER)),
CAR_COLOR_LIST = String.Join(",",clrs.Select(c => c.COLOR_NAME))};
foreach (var item in q)
Console.WriteLine("{0} {1} {2} {3}",
item.CAR_ID,
item.CAR_NAME,
item.CAR_PART_LIST,
item.CAR_COLOR_LIST);
答案 3 :(得分:1)
因此,您有一个CarParts
表,其中每个CarPart
都有一个CarId
和一个PartNumber
;并且您有一个CarColours
表,其中每个CarColour
都有一个Carid
和一个ColourName
。
我假设您不支持隐形车,所以每辆车至少都有一个零件和一种颜色。
您想要一个所有CarIds
的序列,每个CarId
和CarName
,属于这个CarParts
(=此CarId
作为外键)和属于该CarId
的所有ColourNames
的列表(再次使用外键。
要做到这一点,首先我们要获得所有CarId
和所有CarIds with their CarParts
,然后我们可以CarIds with their ColourNames
在通用Join
上获得结果。
如果您认为可能有没有零件或没有颜色的汽车,则需要执行“完全外部联接”而不是常规联接。这不是标准LINQ的一部分,但是您可以自己编写扩展功能。参见LINQ Full Outer Join
在普通CarId上加入联接后,我们将结果与您在CarId上的Cars联接
CarId
最后将所有颜色和零件的汽车连接起来:
var partsGroupedByCarId = carParts.GroupBy( // make groups of carParts
carPart => carPart.CarId); // with common CarId as Key
var coloursGroupedByCarId = carColours.GroupBy( // make groups of carColours
carColour => carColour.CarId);, // with common CarId as Key
var joinResult = partsGroupedByCarId.Join( // Join the two groups
coloursGroupedByCarId,
partGroup => partGroup.Key, // from each group of parts take the key (= CarId)
colourGroup => // from each group of colours take the key (= CarId)
(partGroup, colourGroup) => new // when they match make a new object
{
CarId = partGroup.Key, // with the common CarId
CarParts = partGroup // all partNumbers of the car with CarId
.Select(item => item.PartNumber),
CarColours = colourGroup // all colourNames of the car with carId
.Select(item => item.ColourName),
});
TODO:考虑创建一个大型LINQ语句。由于所有语句都使用延迟执行,因此我认为这不会提高效率。当然会降低可读性。