在 C# 中执行存储过程的最快方法需要最少的代码

发布于 2024-10-30 02:02:12 字数 605 浏览 2 评论 0原文

我将获取实体集合中的结果。我不仅仅需要 IDataReader 对象。因此,考虑到我没有大量参数并且 SP 返回了许多数据列,因此应该回答上面的问题。

请说明理由。

有些可能是

  1. 拖放到 DBML 设计器上,然后通过 linq to sql 调用它。那很好。但这也会生成大量 DBML 代码。越简单越好。

  2. 通过执行ExecuteReader获取IDataReader,然后将IDataReader传递给工厂以创建它的对象。又好又简单。但需要大量编码。返回的每一列都需要以下内容。

int nameIndex = dataReader.GetOrdinal("名称");
if (!dataReader.IsDBNull(nameIndex)){
   myObject.Name = dataReader.GetString(nameIndex);
}

还有其他更简单的选择吗?

更新
@Heinzi 的答案简化了处理结果的过程。有没有更好的方法来处理大量参数?

I'm going to grab the results in a collection of entity. I don't just need the IDataReader object. So above should be answered considering that I've large no of parameters and many columns of data is getting returned by the SP.

Please provide reasons.

A few might be

  1. Drag and drop on to a DBML designer and then calling it by linq to sql. That's very good. But that also generates lot of code for the DBML. Simpler is better.

  2. Getting IDataReader by doing ExecuteReader and then passing IDataReader to factory to create it's object. Good and simple. But requires lot of coding. Below is required for each column returned.

int nameIndex = dataReader.GetOrdinal("Name");
if (!dataReader.IsDBNull(nameIndex)){
   myObject.Name = dataReader.GetString(nameIndex);
}

Are there any other simpler option for this?

UPDATE
@Heinzi's answer simplifies the process of handling the results. Is there any better way to handle large number of parameters also?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

z祗昰~ 2024-11-06 02:02:12

如果您想坚持使用 DataReaders,您可以通过在 IDataReader 上编写扩展方法来节省一些代码,即类似这样的内容(未经测试):

public static T GetValue<T>(this IDataReader reader, string field, T defaultValue)
{
    int index = reader.GetOrdinal(field);
    if (reader.IsDBNull(index)) {
        return defaultValue;
    } else {
        return (T)(reader[name]);
    }
}

这会将您的工厂代码减少为

myObject.Name = dataReader.GetValue<string>("name", Nothing)

当然,此扩展方法的无数变体是可能的(与或者没有 defaultValue,目标字段作为 ref 参数传递以获得与代码完全相同的行为等)。


否则,您可以使用 DataSets 而不是 DataReaders,其中已经存在这样的扩展方法。您可以像这样创建数据集(而不是执行 myCommand.ExecuteReader):

var dataSet = new DataSet();
var adapter = new SqlDataAdapter();
adapter.SelectCommand = myCommand;
adapter.Fill(dataSet);
var table = dataSet.Tables[0];

然后您可以使用 DataRowExtensions.Field

myObject.Name = table.Field<string>("name");
myObject.Age = table.Field<int?>("age") ?? 30;   // default value if DBNull

If you want to stick to DataReaders, you can save some code by writing an extension method on IDataReader, i.e., something like this (untested):

public static T GetValue<T>(this IDataReader reader, string field, T defaultValue)
{
    int index = reader.GetOrdinal(field);
    if (reader.IsDBNull(index)) {
        return defaultValue;
    } else {
        return (T)(reader[name]);
    }
}

This would reduce your factory code to

myObject.Name = dataReader.GetValue<string>("name", Nothing)

Of course, countless variants of this extension method are possible (with or without defaultValue, target field passed as a ref parameter to get exactly the same behavior as your code, etc.).


Otherwise, you could use DataSets instead of DataReaders, where an extension method like this already exists. You create your DataSet like this (instead of executing myCommand.ExecuteReader):

var dataSet = new DataSet();
var adapter = new SqlDataAdapter();
adapter.SelectCommand = myCommand;
adapter.Fill(dataSet);
var table = dataSet.Tables[0];

Then you can access your data using DataRowExtensions.Field:

myObject.Name = table.Field<string>("name");
myObject.Age = table.Field<int?>("age") ?? 30;   // default value if DBNull
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文