2010-07-23 5 views
1

내 질문은 내가 어떻게 사용자 정의 클래스로로드 오전 linq 쿼리에서 반환 된 null 집합을 처리 할 수 ​​있습니다.Linq에서 사용자 정의 목록에 빈 결과 집합을 처리하는 코드 연습

예를

queryResults = queryResults.Select(p => new specialItems(p.ID, p.SECTION, p.PROGRAM, p.EVENT).ToList<specialItems>(); 

...

public class specialItems 
{ 
    public string Id { get; set; } 
    public string Section { get; set; } 
    public string Program { get; set; } 
    public string Event { get; set; } 

    public courseItems(string id, string section, string program, string event) 
    { 
     this.Id = id; 
     this.Section = section; 
     this.Program = program; 
     this.Event = event; 
    } 
} 

결과 세트가 빌 때까지, 나는 얻을 현재이 쿼리가 잘 작동

: 개체의 인스턴스로 설정되지 않았습니다 "개체 참조를 . "

결과 집합이 비어있는 경우 빈 목록을 반환하는 쿼리가 필요합니다.

UPDATE - 변수의 유효하지 않은 재 선언 (고정) 이외에도 문제가 linq 쿼리의 초기 구성에서 더 높다는 것을 알았습니다. 이것은 몇 가지 좋은 제안을 받았을 때 분명 해졌고 오류를 제거했습니다. 일단 원래 질의를 수정하면 일이 순조롭게 진행됩니다.

+0

코드는 유효하지 않습니다. 이미 정의 된 변수를 다시 선언 할 수는 없습니다 ... 또한 새로운 통찰력으로 질문을 업데이트하여 향후 동료 프로그래머에게 혼란을주지 않도록 할 수 있습니다 :-) – jeroenh

+0

문제. 감사. – LeRoy

답변

3

null 병합 연산자 (??)를 사용하십시오.

List<specialItems> queryResults = queryResults.Select(p => new specialItems(p.ID, p.SECTION, p.PROGRAM, p.EVENT).ToList<specialItems>() ?? new List<specialItems>(); 

EDIT : 네가 조금 더 가깝게 보았을 때,이 일이 터지면 터지는 것은 ToList입니다. 약간 쪼개 야 할 수도 있습니다.

var temp = queryResults.Select(p => new specialItems(p.ID, p.SECTION, p.PROGRAM, p.EVENT); 

List<specialItems> results = temp == null ? new List<specialItems>() : temp.ToList<SpecialItems>(); 

이 경우 null 통합 연산자를 넣을 좋은 자리가 없으므로 이렇게해야합니다.

+0

오류가 계속 발생합니다. – LeRoy

+0

다른 접근 방식을 추가했습니다. – Robaticus

+0

두 옵션 모두 실제로 결과를 산출합니다. 두 번째 제안이 실패한 후 체인에 문제가있을 가능성이 높고 내 쿼리에 불량 속성이 삽입 될 수 있다는 사실을 깨달았습니다. 당신의 도움을 주셔서 감사합니다. – LeRoy

3

Robaticus가 대부분 옳다. null 병합 연산자 (??)를 사용한다. Howerver, 스택 추적을 포함하지 않았으므로 queryResults가 처음 null이기 때문에 코드가 throw되고 있다고 가정합니다. 당신이에 도착할 때에는? ?? 연산자를 사용하면 queryResults를 참조 해제하려했기 때문에 이미 예외가 발생했습니다.

또한 코드는 해당 라인에 도달 할 때까지 queryResults가 이미 해당 범위 내에서 정의되어 있기 때문에 의미가 없습니다. 해당 범위에서 이미 로컬로 선언 된 변수는 다시 정의 할 수 없습니다.

List<SpecialItems> queryResults = GetSomeResults(); 
queryResults = (queryResults ?? new List<SpecialItems>()) 
    .Select(p => new SpecialItems(p.ID, p.SECTION, p.PROGRAM, p.EVENT)) 
    .ToList<SpecialItems>(); 

그런 다음, 널 대신 빈 목록을 반환 그렇게하려고, 또는 그 라인에 결과를 합체 queryResults의 원래 버전을 뱉어 기능 또는 라인을 얻을 수 있다면. 그것은 아마도 쿼리 라인에 모든 코드를 가지고있는 것보다 낫습니다.

List<SpecialItems> queryResults = GetSomeResults() ?? new List<SpecialItems>(); 
queryResults = queryResults 
    .Select(p => new SpecialItems(p.ID, p.SECTION, p.PROGRAM, p.EVENT)) 
    .ToList<SpecialItems>(); 
+0

실제로 예외를 던진 () 포함 된 ToList 사실 깨달았다. – Robaticus

+1

@Robaticus - 나는 그가 스택 추적을 추가해야한다고 말했지만, 여전히 라인을 언급 할 것이다. 이것을 디버깅하려면, 코드를 실제로 모든 "."에 새로운 줄/문장으로 분리해야합니다. 그런 다음 스택 추적은 오류를 일으킨 작업을 정확히 가리 킵니다. –

+0

재정의에 대해 죄송합니다. 이것이 내가 제출할 코드를 줄이는 데 필요한 것입니다. 당신은 코드에서 더 높은 쟁점을 가지고있는 것이 옳았습니다. 디버그에 대한 제안에 감사드립니다. – LeRoy

3

Linq는 결과가 없으면 빈 목록을 반환하고, 결코 null이 아닙니다. 따라서 문제는 확실히 queryResults.Select()가 null을 반환하는 것이 아닙니다.

아마도 lazily로 평가되는 linq-to-objects '쿼리'를보고있는 것입니다. ToList()는 그것의 평가를 트리거하고, 아마 nullreference 예외는 체인 위로 높은 람다 (lambda) 표현식에서 발생합니다.

+0

+1, 당신이 말한대로해야합니다. –

+0

좋은 정보! – Mutant

1

Enumerable.Select 또는 Queryable.Select도 Enumerable.ToList도 null을 반환하지 않습니다.

쿼리는 ToList를 열거 할 때까지 인식되지 않습니다. 이 열거 중에 질문에 게시하지 않은 코드로 인해 null 참조 예외가 발생합니다.

함께하고 주석 라인없이이 코드를 고려
List<int> source = Enumerable.Range(1, 10).ToList(); 
IEnumerable<int> query = null; 
try 
{ 
    query = source.Where(i => 1/i > 0); 
} 
catch(Exception ex) 
{ 
    Console.WriteLine("Exception was caught {0}", ex.Message); 
} 
// source.Add(0); 
List<int> result = query.ToList(); 

함께하고 주석 라인없이이 코드를 고려하십시오 : 당신이 제공

DataContext myDC = new DataContext(); 
string name = null; 
IQueryable<Person> query = myDC.Persons.Where(p => p.Name.StartsWith(name)); 
// name = "Zz"; 
List<Person> result = query.ToList(); 
관련 문제