2013-10-02 35 views
1

我想從下面的linq查詢中獲取IEnumerable。我究竟做錯了什麼?無法將原始SQL查詢映射到DataRow

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

執行代碼時會發生什麼?你是否看到任何異常?意外的結果? –

回答

3

DataRow類沒有默認的(無參數)構造函數,所以你不能把它作爲查詢參數的類型。有對類型參數沒有通用的約束,並在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)); 
     // ... 
} 

BTW映射到的DataRow是沒有意義的,即使它有默認公共構造。因爲它不是簡單的基本類型,並且它沒有與查詢返回的列的名稱相匹配的屬性(是的,映射只使用屬性)。

的LINQ的正確使用將

IEnumerable<Customer> results = context.Customers; 

,將產生SELECT * FROM Customer查詢,地圖查詢結果對客戶的實體。如果你真的想使用原始SQL:

IEnumerable<Customer> results = 
    context.Database.SqlQuery<Customer>("SELECT * FROM Customers"); 
0

我認爲,我們試圖解決同樣的問題(谷歌使我在這裏,反正)。我通過SqlQuery<TElement>(string sql, params object[] parameters執行原始SQL命令,並希望在單元測試中聲明從查詢返回的結果的單個屬性。

我所謂的方法:

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

並驗證它返回的數據:

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

我定義我的測試類中的私有類Customer(不幸的是,我沒有使用實體框架):

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

客戶的屬性必須匹配在SQL查詢中返回的列名稱,它們必須是屬性(而不僅僅是Customer類的變量。您不必爲查詢返回的所有列創建屬性。