6

データベース テーブルを C# の型にマップするためだけに Dapper を使用しようとしていますが、一部の型では、テーブルにない追加の要素が必要です。これを行うために、列の値を取り、適切なプロパティを設定できるファクトリを使用しています。

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>ですか? これを機能させるにはどうすればよいですか? これは単に間違ったアプローチであり、より良い方法がありますか?

4

2 に答える 2

10

最も簡単な修正は、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>です。

もう 1 つのオプションは、ジェネリック型引数を に指定することSelectです。

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

それはラムダ式をaに強制しようとしていますFunc<dynamic, IMyType>-私はそれがうまくいくと信じています...

編集:コメントに記載されているように、コンパイル時にメソッド呼び出しを強制的に解決すると、それも修正されます。基本的に、最も読みやすいものに依存します。

于 2011-08-30T18:11:02.620 に答える
1

最善の修正は、おそらく選択ステートメントから動的呼び出しを削除することです。そうすれば、予想される static type が得られます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)); 
}
于 2011-08-30T18:21:11.520 に答える