如何确定存储过程结果的列是否可以为空
我正在编写一个代码生成器,但在确定存储过程结果集列的可为空状态时陷入困境。我可以很好地查询 DataType,但 datareader 对象和数据表列都不包含我的列的正确可为空值。
public List<DataColumn> GetColumnInfoFromStoredProcResult(string schema, string storedProcName)
{
//build sql text
var sb = new StringBuilder();
sb.Append("SET FMTONLY OFF; SET FMTONLY ON; \n");//this is how EF4.1 did so I copied..not sure why the repeat
sb.Append(String.Format("exec {0}.{1} ", schema, storedProcName));
var prms = GetStoredProcedureParameters(schema: schema, sprocName: storedProcName);
var count = 1;
foreach (var param in prms)
{
sb.Append(String.Format("{0}=null", param.Name));
if (count < prms.Count)
{
sb.Append(", ");
}
count++;
}
sb.Append("\n SET FMTONLY OFF; SET FMTONLY OFF;");
var dataTable = new DataTable();
//var list = new List<DataColumn>();
using (var sqlConnection = this.SqlConnection)
{
using (var sqlAdapter = new SqlDataAdapter(sb.ToString(), sqlConnection))
{
if (sqlConnection.State != ConnectionState.Open) sqlConnection.Open();
sqlAdapter.SelectCommand.ExecuteReader(CommandBehavior.KeyInfo);
sqlConnection.Close();
sqlAdapter.Fill(dataTable);
}
//using (var sqlCommand = new SqlCommand())
//{
// sqlCommand.CommandText = sb.ToString();
// sqlCommand.CommandType = CommandType.Text;
// sqlCommand.Connection = sqlConnection;
// if (sqlConnection.State != ConnectionState.Open) sqlConnection.Open();
// var dr = sqlCommand.ExecuteReader(CommandBehavior.SchemaOnly);
// var whateva = dr.GetSchemaTable();
// foreach (DataColumn col in whateva.Columns)
// {
// list.Add(col);
// }
//}
}
var list = dataTable.Columns.Cast<DataColumn>().ToList();
return list;
}
我试图最终得到类似于实体框架从存储过程创建复杂类型的结果。我可以劫持该功能吗?
在此示例中,Id 列.. tblJobId(不是我的命名约定)永远不会为 null。但是我选择 null 作为 ImNull,它具有所有相同的属性,那么 EF 如何确定相应的 C# 数据类型是否可以为 null ?
有没有人这样做过..
想法受到赞赏。
I'm writing a code generator and am getting stuck on determining the nullable status of a stored procedure result set Column. I can query the DataType just fine but neither the datareader object nor a data table column contain the correct nullable value of my column.
public List<DataColumn> GetColumnInfoFromStoredProcResult(string schema, string storedProcName)
{
//build sql text
var sb = new StringBuilder();
sb.Append("SET FMTONLY OFF; SET FMTONLY ON; \n");//this is how EF4.1 did so I copied..not sure why the repeat
sb.Append(String.Format("exec {0}.{1} ", schema, storedProcName));
var prms = GetStoredProcedureParameters(schema: schema, sprocName: storedProcName);
var count = 1;
foreach (var param in prms)
{
sb.Append(String.Format("{0}=null", param.Name));
if (count < prms.Count)
{
sb.Append(", ");
}
count++;
}
sb.Append("\n SET FMTONLY OFF; SET FMTONLY OFF;");
var dataTable = new DataTable();
//var list = new List<DataColumn>();
using (var sqlConnection = this.SqlConnection)
{
using (var sqlAdapter = new SqlDataAdapter(sb.ToString(), sqlConnection))
{
if (sqlConnection.State != ConnectionState.Open) sqlConnection.Open();
sqlAdapter.SelectCommand.ExecuteReader(CommandBehavior.KeyInfo);
sqlConnection.Close();
sqlAdapter.Fill(dataTable);
}
//using (var sqlCommand = new SqlCommand())
//{
// sqlCommand.CommandText = sb.ToString();
// sqlCommand.CommandType = CommandType.Text;
// sqlCommand.Connection = sqlConnection;
// if (sqlConnection.State != ConnectionState.Open) sqlConnection.Open();
// var dr = sqlCommand.ExecuteReader(CommandBehavior.SchemaOnly);
// var whateva = dr.GetSchemaTable();
// foreach (DataColumn col in whateva.Columns)
// {
// list.Add(col);
// }
//}
}
var list = dataTable.Columns.Cast<DataColumn>().ToList();
return list;
}
I'm trying to end up with something similar to the the Entities Framework creation of a complex type from a stored procedure. Can I hijack that functionality?
On this example the Id column.. tblJobId (not my naming convention) would never be null.. But I selected null as ImNull and it has all the same properties so how does EF determine if the corresponding C# data type should be nullable or not?
Has anybody done this..
Ideas are appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
秘诀是仅使用架构并填充数据集而不是数据表。现在,数据列上的AllowDbNull 属性可以正确显示返回值的可为空状态。
就是这个...
The secret was to use Schema Only and fill a dataset not datatable. Now the AllowDbNull property on the datacolumn properly displays the nullable status of the return value.
This was it...
假设来自 SP 的每一列都可以为空 - 这是一个有效的假设,因为存储过程 - 它是一种数据抽象层,因此它的代码可以更改,但仍然会产生有效的结果。
如果昨天列不可为空,那么今天就没有任何意义。因此,来自 SP 结果集的所有列在设计上都可以为空。
更新。
假设表 t1 有列
Id INT IDENTITY PRIMARY KEY
您的存储过程如下所示:
因此它永远不会返回 Id = NULL,但这是 SP -数据的抽象,所以 - 明天我将像这样修改它:
所以,现在它返回 NULL - 想想这个。对数据抽象理解的差异
Assume, that every column which comes from SP can be null - this is a valid assumption because stored procedure - its a kind of data abstraction layer and thus its code can change but still produce valid results.
If column was non-nullable yesterday it means nothing for today. So - all the columns which come from SP resultsets are nullable by design.
Update.
Assuming that table t1 has column
Id INT IDENTITY PRIMARY KEY
Your stored proc looks like this:
So it will never return an Id = NULL, but this is the SP - an abstraction of data, so - tomorrow i'll modify it like this:
So, now it returns NULL - think about this. The difference in understanding of data abstraction