我在一个包含大约600列的表上运行以下查询:
SELECT *
FROM Table
WHERE [Owner] = 1234
我使用EF代码优先和Dapper运行此查询,我遇到了同样的问题.
特别是许多具有值的行从查询返回为DBNull(我使用SQL Server Management Studio验证了列具有数据).奇怪的是,只有在请求所有列时才会发生(无论是使用*还是显式拉动它们).
例如,如果列Status具有值“A”,则查询将返回DBNull作为其值.但如果不是上面的代码(拉动600列),我使用此查询:
SELECT [Status]
FROM Table
WHERE [Owner] = 1234
“状态”列已正确填充.
这是我用来处理结果的Dapper代码:
public IList<Dictionary<string, string>> GetData() {
var sql = "SELECT * FROM Table WHERE [Owner] = 1234";
var cn = new SqlConnection(serverConnectionString);
var rows = new List<Dictionary<string, string>>();
using (var reader = cn.ExecuteReader(sql))
{
while (reader.Read())
{
var dict = new Dictionary<string, string>();
for (var i = 0; i < reader.FieldCount; i++)
{
var propName = reader.GetName(i).ToLowerInvariant();
// This is set to DBNull for most, but not all,
// columns if querying the ~600 columns in the Table
var propValue = reader.GetValue(i);
dict[propName] = propValue?.ToString();
}
rows.Add(dict);
}
}
return rows;
}
我无法做出这种行为的头或尾.任何帮助将不胜感激.
最佳答案 尝试使用Dapper的.Query()扩展来返回动态对象列表.以下是一个快速测试:
[Test]
public void Test_Large_Number_of_Columns()
{
const int n = 600;
var cols = "";
for (var i = 0; i < n; i++)
{
cols += "col" + i + " varchar(50) null,";
}
var create = String.Format("IF OBJECT_ID('dbo.foo', 'U') IS NOT NULL DROP TABLE dbo.foo; create table foo({0})", cols);
using (var conn = new SqlConnection(@"Data Source=.\sqlexpress;Integrated Security=true; Initial Catalog=foo"))
{
conn.Execute(create);
conn.Execute("insert into foo(col300) values('hello') ");
var result = conn.Query("select * from foo").AsList();
Assert.That(result[0].col300, Is.EqualTo("hello"));
}
}