관계 부분은 Codd의 프리미티브 관계 연산자 중 하나이며, 모든 부분을 제공하는 공급자로 구어체로 알려져 있습니다. 예를 들어 SQL에 다양한 번역이있었습니다. Celko는 the pilots who can fly all the planes in the hangar의 예를 사용하여 몇 가지 접근법에 대해 설명합니다.LINQ의 관계 구분?
내가 선호하는 것은 "나머지와 함께"(즉, 윌슨도 F-17 전투기를 비행 할 수 있지만 격납고에는 하나도 없기 때문입니다.)
WITH PilotSkills
AS
(
SELECT *
FROM (
VALUES ('Celko', 'Piper Cub'),
('Higgins', 'B-52 Bomber'), ('Higgins', 'F-14 Fighter'),
('Higgins', 'Piper Cub'),
('Jones', 'B-52 Bomber'), ('Jones', 'F-14 Fighter'),
('Smith', 'B-1 Bomber'), ('Smith', 'B-52 Bomber'),
('Smith', 'F-14 Fighter'),
('Wilson', 'B-1 Bomber'), ('Wilson', 'B-52 Bomber'),
('Wilson', 'F-14 Fighter'), ('Wilson', 'F-17 Fighter')
) AS T (pilot_name, plane_name)
),
Hangar
AS
(
SELECT *
FROM (
VALUES ('B-1 Bomber'),
('B-52 Bomber'),
('F-14 Fighter')
) AS T (plane_name)
)
SELECT DISTINCT pilot_name
FROM PilotSkills AS P1
WHERE NOT EXISTS (
SELECT plane_name
FROM Hangar
EXCEPT
SELECT plane_name
FROM PilotSkills AS P2
WHERE P1.pilot_name = P2.pilot_name
);
가 지금은 객체에 LINQ에서이 작업을 수행 할 필요가 : 제수가 빈 세트 (격납고가 비어 즉 때 모든 조종사가 반환)입니다. 제안 된 직접 번역본은 다음과 같습니다.
var hangar = new []
{
new { PlaneName = "B-1 Bomber" },
new { PlaneName = "F-14 Fighter" },
new { PlaneName = "B-52 Bomber" }
}.AsEnumerable();
var pilotSkills = new []
{
new { PilotName = "Celko", PlaneName = "Piper Cub" },
new { PilotName = "Higgins", PlaneName = "B-52 Bomber" },
new { PilotName = "Higgins", PlaneName = "F-14 Fighter" },
new { PilotName = "Higgins", PlaneName = "Piper Cub" },
new { PilotName = "Jones", PlaneName = "B-52 Bomber" },
new { PilotName = "Jones", PlaneName = "F-14 Fighter" },
new { PilotName = "Smith", PlaneName = "B-1 Bomber" },
new { PilotName = "Smith", PlaneName = "B-52 Bomber" },
new { PilotName = "Smith", PlaneName = "F-14 Fighter" },
new { PilotName = "Wilson", PlaneName = "B-1 Bomber" },
new { PilotName = "Wilson", PlaneName = "B-52 Bomber" },
new { PilotName = "Wilson", PlaneName = "F-14 Fighter" },
new { PilotName = "Wilson", PlaneName = "F-17 Fighter" }
}.AsEnumerable();
var actual = pilotSkills.Where
(
p1 => hangar.Except
(
pilotSkills.Where(p2 => p2.PilotName == p1.PilotName)
.Select(p2 => new { p2.PlaneName })
).Any() == false
).Select(p1 => new { p1.PilotName }).Distinct();
var expected = new []
{
new { PilotName = "Smith" },
new { PilotName = "Wilson" }
};
Assert.That(actual, Is.EquivalentTo(expected));
LINQ is supposedly based on the relational algebra 다음은 직접적인 번역입니다. 그러나 더 나은 '기본'LINQ 접근 방식이 있습니까? @Daniel Hilgarth의 대답에 반영
, .NET 땅에있는 데이터로 시작하는 '그룹화'될 가능성이 :
var pilotSkills = new []
{
new { PilotName = "Celko",
Planes = new []
{ new { PlaneName = "Piper Cub" }, } },
new { PilotName = "Higgins",
Planes = new []
{ new { PlaneName = "B-52 Bomber" },
new { PlaneName = "F-14 Fighter" },
new { PlaneName = "Piper Cub" }, } },
new { PilotName = "Jones",
Planes = new []
{ new { PlaneName = "B-52 Bomber" },
new { PlaneName = "F-14 Fighter" }, } },
new { PilotName = "Smith",
Planes = new []
{ new { PlaneName = "B-1 Bomber" },
new { PlaneName = "B-52 Bomber" },
new { PlaneName = "F-14 Fighter" }, } },
new { PilotName = "Wilson",
Planes = new []
{ new { PlaneName = "B-1 Bomber" },
new { PlaneName = "B-52 Bomber" },
new { PlaneName = "F-14 Fighter" },
new { PlaneName = "F-17 Fighter" }, } },
};
... 그냥 이름을 투사하는 만들기, 임의 훨씬 더 간단 잠재적 인 솔루션 :
// Easy to understand at a glance:
var actual1 = pilotSkills.Where(x => hangar.All(y => x.Planes.Contains(y)));
// Potentially more efficient:
var actual = pilotSkills.Where(x => !hangar.Except(x.Planes).Any());
당신은 배열 –
커드의 부문 원시적되지는 IEnumerable있다는'AsEnumerable을()'이 필요하지 않습니다. 그리고 비공식적으로 그것은 적어도 하나의 부품을 공급하는 "모든 부품을 공급하는 공급 업체"*와 *를 반환합니다. (비록 당신의 비공식적 인 표현이 슬프게도 공통적 인 것이라는 것에 동의하지만) 실제로 그렇게 유용하지는 않습니다. "접근법"은 원본의 "번역"이 아니며 원본 * 및 다른 그러나 연상되는 * 연산자의 번역입니다. (베스트/관계형 하위 집합 연산자의 관점에서 가장 쉬운 이유는 다음 대수학/미적분으로 변환합니다.) 추신 : "LINQ는 아마도 관계형 대수학을 기반으로합니다"- 하하. 영감을 얻어, OK. – philipxy
@philipxy 내가 인용 한 기사에서 인용 : "이 기사에서는 관계형 대수학의 일반화로서 모나드와 LINQ를 설명합니다." 당신이 논박에 대한 표창장을 가지고 있다면 나는 매우 관심이있을 것입니다. 마찬가지로, 나는 분열이 원시적이라고 암시하려는 것이 아니고 내가 가지고 있다고 생각하지 않는다. 내가 링크 된 기사는 (다소 비공식적으로) Todd와 Romley를 언급합니다. 그러나 부서가 기본 운영자가 아닌 이유에 대해 읽으려는 무언가가 있다면 감사하게 받아 들여야합니다. – onedaywhen