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>'型に戻すことはできません

私の工場クラスは次のようになります:

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>を実装すると仮定する理由はありません。

2番目のフォームが実際に何も追加していないように見えることに同意しますが、コンパイラは_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