我们实际上基于 ADOMD 数据提供程序编写了自己的 .NET Framework 数据提供程序。我们希望在今年晚些时候将其开源,但以下是我如何完成您想要完成的任务的一些摘录。
我使用了 AdomdCommand 对象的 ExecuteXmlReader。返回的 xml 将包含单元格的一部分。
AdomdCommand command = new AdomdCommand();
command.Connection = new AdomdConnection(connectionString);
command.Connection.Open();
command.CommandText = query;
var doc = XDcoument.Load(command.ExecuteXmlReader());
var cellData = from cell in doc.Root.Elements(_namespace + "CellData").Elements(_namespace + "Cell")
select new
{
Ordinal = (int)cell.Attribute("CellOrdinal"),
FormattedValue = cell.Elements(_namespace + "FmtValue").Any() ? cell.Element(_namespace + "FmtValue").Value : cell.Element(_namespace + "Value").Value,
Value = cell.Element(_namespace + "Value").Value,
Type = (string)cell.Element(_namespace + "Value").Attribute(_xsiNs + "type"),
};
每个单元格都有一个数据类型。对于给定的列,我们需要该列中的所有单元格。
var x = cells.Where(c => ((c.Ordinal + 1) % columnCount) == columnPosition).Select(t => t.Type).Distinct();
if (x.Count() > 1)
{
// if a non number comes back, the type is null, so non numbers are null
// on counts of greater than 1 and no nulls, we have multiple number types, make them all double to accommodate the differences
if ( !x.Contains(null) )
{
// mix of numbers not doubles, default to int
if (!x.Contains("xsd:double"))
{
type = typeof(int);
}
else
{
type = typeof(double);
}
}
else
{
type = typeof(string);
}
}
else
{
// entire column maybe null, default to string, otherwise check
if (x.Count() == 1)
{
type = ConvertXmlTypeToType(x.First());
}
}
终于有了将 Xml 类型转换为 .NET 类型的函数
private Type ConvertXmlTypeToType(string type)
{
Type t = typeof(string);
switch (type)
{
case "xsd:int":
t = typeof(int);
break;
case "xsd:double":
t = typeof(double);
break;
case "xsd:long":
t = typeof(long);
break;
case "xsd:short":
t = typeof(short);
break;
case "xsd:integer":
t = typeof(int);
break;
case "xsd:decimal":
t = typeof(decimal);
break;
case "xsd:float":
t = typeof(float);
break;
default:
t = typeof(string);
break;
}
return t;
}