• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

loresoft / FluentCommand / 23256000174

18 Mar 2026 04:13PM UTC coverage: 56.658% (+0.2%) from 56.486%
23256000174

push

github

pwelter34
Add SQL Server structured parameter support

1303 of 2875 branches covered (45.32%)

Branch coverage included in aggregate %.

106 of 149 new or added lines in 8 files covered. (71.14%)

6 existing lines in 1 file now uncovered.

3969 of 6430 relevant lines covered (61.73%)

361.39 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

48.68
/src/FluentCommand.SqlServer/SqlCommandExtensions.cs
1
using System.Data;
2
using System.Data.Common;
3

4
using Microsoft.Data.SqlClient;
5
using Microsoft.Data.SqlClient.Server;
6

7
namespace FluentCommand;
8

9
/// <summary>
10
/// Extension methods for <see cref="IDataCommand"/> specific to SQL Server.
11
/// </summary>
12
public static class SqlCommandExtensions
13
{
14
    /// <summary>
15
    /// Adds a new SQL Server structured table-valued parameter with the specified <paramref name="name"/> and <paramref name="data"/>.
16
    /// Uses <see cref="SqlDataRecordAdapter{T}"/> internally for maximum efficiency by reusing a single record per row
17
    /// with cached metadata per type.
18
    /// </summary>
19
    /// <typeparam name="TEntity">The type of the data entities.</typeparam>
20
    /// <param name="dataCommand">The <see cref="IDataCommand"/> to extend.</param>
21
    /// <param name="name">The name of the parameter.</param>
22
    /// <param name="data">The enumerable data to be added as a table-valued parameter.</param>
23
    /// <returns>
24
    /// The same <see cref="IDataCommand"/> instance for fluent chaining.
25
    /// </returns>
26
    public static IDataCommand ParameterStructured<TEntity>(this IDataCommand dataCommand, string name, IEnumerable<TEntity> data)
27
        where TEntity : class
28
    {
29
        if (dataCommand is null)
3!
NEW
30
            throw new ArgumentNullException(nameof(dataCommand));
×
31

32
        if (string.IsNullOrEmpty(name))
3!
NEW
33
            throw new ArgumentException($"'{nameof(name)}' cannot be null or empty.", nameof(name));
×
34

35
        if (data is null)
3!
NEW
36
            throw new ArgumentNullException(nameof(data));
×
37

38
        var records = new SqlDataRecordAdapter<TEntity>(data);
3✔
39
        return ParameterStructured(dataCommand, name, records);
3✔
40
    }
41

42
    /// <summary>
43
    /// Adds a new SQL Server structured table-valued parameter with the specified <paramref name="name"/> and <paramref name="records"/>.
44
    /// Uses <see cref="IEnumerable{SqlDataRecord}"/> for maximum efficiency with minimal memory allocation.
45
    /// </summary>
46
    /// <param name="dataCommand">The <see cref="IDataCommand"/> to extend.</param>
47
    /// <param name="name">The name of the parameter.</param>
48
    /// <param name="records">The <see cref="IEnumerable{SqlDataRecord}"/> to be added as a table-valued parameter.</param>
49
    /// <returns>
50
    /// The same <see cref="IDataCommand"/> instance for fluent chaining.
51
    /// </returns>
52
    /// <exception cref="InvalidOperationException">
53
    /// Thrown if the underlying command is not a SQL Server command.
54
    /// </exception>
55
    public static IDataCommand ParameterStructured(this IDataCommand dataCommand, string name, IEnumerable<SqlDataRecord> records)
56
    {
57
        if (dataCommand is null)
3!
NEW
58
            throw new ArgumentNullException(nameof(dataCommand));
×
59

60
        if (string.IsNullOrEmpty(name))
3!
NEW
61
            throw new ArgumentException($"'{nameof(name)}' cannot be null or empty.", nameof(name));
×
62

63
        if (records is null)
3!
NEW
64
            throw new ArgumentNullException(nameof(records));
×
65

66
        var sqlParameter = CreateSqlParameter(dataCommand);
3✔
67

68
        sqlParameter.ParameterName = name;
3✔
69
        sqlParameter.Value = records;
3✔
70
        sqlParameter.Direction = ParameterDirection.Input;
3✔
71
        sqlParameter.SqlDbType = SqlDbType.Structured;
3✔
72

73
        return dataCommand.Parameter(sqlParameter);
3✔
74
    }
75

76
    /// <summary>
77
    /// Adds a new SQL Server structured table-valued parameter with the specified <paramref name="name"/> and <paramref name="dataReader"/>.
78
    /// Uses <see cref="DbDataReader"/> for streaming data to the server without materializing to a <see cref="DataTable"/>.
79
    /// </summary>
80
    /// <param name="dataCommand">The <see cref="IDataCommand"/> to extend.</param>
81
    /// <param name="name">The name of the parameter.</param>
82
    /// <param name="dataReader">The <see cref="DbDataReader"/> to be added as a table-valued parameter.</param>
83
    /// <returns>
84
    /// The same <see cref="IDataCommand"/> instance for fluent chaining.
85
    /// </returns>
86
    /// <exception cref="InvalidOperationException">
87
    /// Thrown if the underlying command is not a SQL Server command.
88
    /// </exception>
89
    public static IDataCommand ParameterStructured(this IDataCommand dataCommand, string name, DbDataReader dataReader)
90
    {
NEW
91
        if (dataCommand is null)
×
NEW
92
            throw new ArgumentNullException(nameof(dataCommand));
×
93

NEW
94
        if (string.IsNullOrEmpty(name))
×
NEW
95
            throw new ArgumentException($"'{nameof(name)}' cannot be null or empty.", nameof(name));
×
96

NEW
97
        if (dataReader is null)
×
NEW
98
            throw new ArgumentNullException(nameof(dataReader));
×
99

NEW
100
        var sqlParameter = CreateSqlParameter(dataCommand);
×
101

NEW
102
        sqlParameter.ParameterName = name;
×
NEW
103
        sqlParameter.Value = dataReader;
×
NEW
104
        sqlParameter.Direction = ParameterDirection.Input;
×
NEW
105
        sqlParameter.SqlDbType = SqlDbType.Structured;
×
106

NEW
107
        return dataCommand.Parameter(sqlParameter);
×
108
    }
109

110
    /// <summary>
111
    /// Adds a new SQL Server structured table-valued parameter with the specified <paramref name="name"/> and <paramref name="dataTable"/>.
112
    /// </summary>
113
    /// <param name="dataCommand">The <see cref="IDataCommand"/> to extend.</param>
114
    /// <param name="name">The name of the parameter.</param>
115
    /// <param name="dataTable">The <see cref="DataTable"/> to be added as a table-valued parameter.</param>
116
    /// <returns>
117
    /// The same <see cref="IDataCommand"/> instance for fluent chaining.
118
    /// </returns>
119
    /// <exception cref="InvalidOperationException">
120
    /// Thrown if the underlying command is not a SQL Server command.
121
    /// </exception>
122
    public static IDataCommand ParameterStructured(this IDataCommand dataCommand, string name, DataTable dataTable)
123
    {
124
        if (dataCommand is null)
2!
NEW
125
            throw new ArgumentNullException(nameof(dataCommand));
×
126

127
        if (string.IsNullOrEmpty(name))
2!
NEW
128
            throw new ArgumentException($"'{nameof(name)}' cannot be null or empty.", nameof(name));
×
129

130
        if (dataTable is null)
2!
NEW
131
            throw new ArgumentNullException(nameof(dataTable));
×
132

133
        var sqlParameter = CreateSqlParameter(dataCommand);
2✔
134

135
        sqlParameter.ParameterName = name;
2✔
136
        sqlParameter.Value = dataTable;
2✔
137
        sqlParameter.Direction = ParameterDirection.Input;
2✔
138
        sqlParameter.SqlDbType = SqlDbType.Structured;
2✔
139

140
        return dataCommand.Parameter(sqlParameter);
2✔
141
    }
142

143
    private static SqlParameter CreateSqlParameter(IDataCommand dataCommand)
144
    {
145
        var parameter = dataCommand.Command.CreateParameter();
5✔
146
        var sqlParameter = parameter as SqlParameter;
5✔
147
        if (sqlParameter == null)
5!
NEW
148
            throw new InvalidOperationException(
×
NEW
149
                "SqlParameter only supported by SQL Server.  Make sure DataSession was created with a valid SqlConnection.");
×
150

151
        return sqlParameter;
5✔
152
    }
153
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc