2

以下のlinqクエリからIEnumerableを取得しようとしています。私は何を間違っていますか?

IEnumerable<DataRow> results = 
    context.Database.SqlQuery<DataRow>("SELECT * FROM Customer").AsEnumerable();
4

2 に答える 2

3

DataRowclass にはデフォルト (パラメーターなし) のコンストラクターがないため、クエリ パラメーターの型として使用することはできません。型パラメーターには一般的な制約はなく、 MSDNには何も記載されていません(!) が、パラメーター型に既定のコンストラクターがない場合、列マップ ファクトリは例外をスローします。

結果の型 'System.Data.DataRow' は抽象ではない可能性があり、既定のコンストラクターを含める必要があります。

この例外をスローするコードは次のとおりです。

internal static CollectionColumnMap CreateColumnMapFromReaderAndClrType(
    DbDataReader reader, Type type, MetadataWorkspace workspace)
{
      BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
      ConstructorInfo constructor = type.GetConstructor(flags, (Binder) null, Type.EmptyTypes, (ParameterModifier[]) null);
      if (type.IsAbstract || (ConstructorInfo) null == constructor && !type.IsValueType)
          throw EntityUtil.InvalidOperation(InvalidTypeForStoreQuery((object) type));
      // ...
}

ところで、DataRow へのマッピングは、デフォルトのパブリック コンストラクターがあったとしても意味がありません。これは単純なプリミティブ型ではなく、クエリから返された列の名前と一致するプロパティがないためです (はい、マッピングはプロパティのみを使用します)。

Linqの正しい使い方は

IEnumerable<Customer> results = context.Customers;

これにより、クエリが生成されSELECT * FROM Customer、クエリ結果が顧客エンティティにマップされます。本当に生の SQL を使用したい場合:

IEnumerable<Customer> results = 
     context.Database.SqlQuery<Customer>("SELECT * FROM Customers");
于 2013-10-02T22:42:58.643 に答える
0

私たちは同じ問題を解決しようとしていたと思います (とにかく、Google が私をここに導いてくれました)。生の SQL コマンドを実行SqlQuery<TElement>(string sql, params object[] parametersしており、単体テストでクエリから返された結果の個々のプロパティをアサートしたいと考えていました。

メソッドを呼び出しました:

var result = (db.SqlQuery<Customer>("select * from customers").First();

返されたデータを検証しました。

Assert.AreEqual("John", result.FirstName);

テストクラス内にプライベート クラスを定義しましたCustomer(残念ながら、Entity Framework は使用していません)。

private class Customer
{
    public string FirstName { get; set; }
}

Customer のプロパティは、SQL クエリで返される列名と一致する必要があり、プロパティである必要があります (Customerクラスの変数だけではありません。クエリから返されるすべての列のプロパティを作成する必要はありません。

于 2014-03-12T02:26:11.793 に答える