Select ()가 IEnumerable을 변환하지 않는 이유는 무엇입니까? IEnumerable에 ?

c# dapper linq

문제

Dapper를 사용하여 데이터베이스 테이블을 C #의 유형에 매핑하기 만하면됩니다. 그러나 일부 유형은 테이블에없는 추가 요소가 필요합니다. 이렇게하려면 열 값을 가져 와서 적절한 속성을 설정할 수있는 팩토리를 사용하고 있습니다.

public IEnumerable<IMyType> All() {
  var query = _connection.Query("SELECT * FROM [table]");
  return query.Select(o => _myTypeFactory.Create(o));
}

현재이 때문에 return 문에서 오류가 발생합니다.

식 형식 'System.Collections.Generic.IEnumerable<dynamic>''System.Collections.Generic.IEnumerable<IMyType>' 형식으로 변환 할 수 없습니다.

내 factory 클래스는 다음과 같이 보입니다.

public class MyTypeFactory {
  public IMyType Create(dynamic o) {
    return Create((String) o.Code, (Int32) o.KeyID);
  }
  public IMyType Create(String code, Int32 keyID) {
    return new MyType(code, Cache.Lookup(keyID));
  }
}

Select() 메서드가 IEnumerable<IMyType> 반환하지 않는 이유는 무엇입니까? 이 작업을하려면 무엇을해야합니까? 이것은 잘못된 접근 일뿐 더 좋은 방법이 있습니까?

수락 된 답변

가장 간단한 수정은 Cast<> LINQ 연산자를 사용하는 것입니다.

public IEnumerable<IMyType> All() {
  var query = _connection.Query("SELECT * FROM [table]");
  return query.Select(o => _myTypeFactory.Create(o))
              .Cast<IMyType>();
}

또는 각 요소를 캐스팅 할 수 있습니다.

public IEnumerable<IMyType> All() {
  var query = _connection.Query("SELECT * FROM [table]");
  return query.Select(o => (IMyType) _myTypeFactory.Create(o));
}

IEnumerable<dynamic>IEnumerable<IMyType> 사이에는 암묵적인 변환을 사용할 수 없기 때문에 현재는 작동하지 않습니다. IEnumerable<dynamic> 은 여러 가지 방법으로 구현 될 수 있으며 각 항목이 동적으로 생성 되므로 결과 값이 IEnumerable<IMyType> 구현한다고 가정 할 이유가 없습니다.

나는 두 번째 양식이 실제로 아무것도 추가되지 않지만 컴파일러는 모든 가능한 반환 유형을 확인하지 않는 것 같습니다 동의 _myTypeFactory.Create(o) - 식이다 즉 그것은 동적 값으로 전체 표현식 것으로 취급 dynamic 유형. 따라서 Select 결과는 여전히 IEnumerable<dynamic> 유형입니다.

또 다른 옵션은 Select 제네릭 형식 인수를 지정하는 것입니다.

public IEnumerable<IMyType> All() {
  var query = _connection.Query("SELECT * FROM [table]");
  return query.Select<IMyType>(o => _myTypeFactory.Create(o));
}

그건 람다 표현식을 Func<dynamic, IMyType> 으로 강제 변환하려고 시도한 것입니다 - 작동 한다고 믿습니다 ...

편집 : 코멘트에 명시된 바와 같이, 메소드 호출을 컴파일 타임에 해결하도록 강요하면 수정 될 것이다. 기본적으로 그것은 당신이 가장 잘 읽을 수있는 것을 찾는다.


인기 답변

가장 좋은 해결 방법은 select 문에서 동적 호출을 제거하는 것입니다. 그러면 예상되는 정적 유형 IEnumerable<IMyType> 됩니다.

public IEnumerable<IMyType> All() {
  var query = _connection.Query("SELECT * FROM [table]");
  return query.Select(o => _myTypeFactory.Create((Object)o)); //cast dynamic type to Object
}

또는

public IEnumerable<IMyType> All() {
      IEnumerable<object> query = _connection.Query("SELECT * FROM [table]"); //IEnumerable<dynamic> is the same as IEnumerable<object>
      return query.Select(o => _myTypeFactory.Create(o)); 
}


아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow