C# 转换整数数组以在SQL中使用;在;条款
当然,有一种框架方法可以将给定的整数、字符串等数组转换为一个列表,该列表可以在SQL“C# 转换整数数组以在SQL中使用;在;条款,c#,sql,arrays,C#,Sql,Arrays,当然,有一种框架方法可以将给定的整数、字符串等数组转换为一个列表,该列表可以在SQL“in”子句中使用 e、 g 会去 "(1,2,3)" 注意:您不再需要在.NET Framework 4中调用.ToArray()。添加了一个新方法。如果您无权访问.NET 3.5扩展方法,可以执行以下操作: StringBuilder sb = new StringBuilder(); sb.Append('('); foreach (int i in values) { sb.Append(i)
in
”子句中使用
e、 g
会去
"(1,2,3)"
注意:您不再需要在.NET Framework 4中调用
.ToArray()
。添加了一个新方法。如果您无权访问.NET 3.5扩展方法,可以执行以下操作:
StringBuilder sb = new StringBuilder();
sb.Append('(');
foreach (int i in values) {
sb.Append(i).Append(',');
}
// remove final ,
sb.Length -= 1;
sb.Append(')');
string inValue = sb.ToString();
可以在.NET 2上使用的方法,如下所示:
var str = "(" + string.Join(", ", Array.ConvertAll(values, v => v.ToString(CultureInfo.InvariantCulture)));
假设
values
是一个数组,array.ConvertAll
应该比使用ToArray的LINQ更高效
这也可以在一行中完成
public string ToInStatement(this int[] values) {
string[] stringValues =
Array.ConvertAll<int, string>(values, Convert.ToString);
string result = "(" + String.Join(",", stringValues) + ")";
return result;
}
公共字符串到安装(此int[]值){
字符串[]字符串值=
ConvertAll(值,Convert.ToString);
字符串结果=“(“+string.Join”(“,”,stringValues)+”);
返回结果;
}
嘿,很好的建议,下面只是一个小小的修改
public static class IEnumerableExtensions
{
// reasonable to assume you will use this everywhere, not just
// Sql statements, but log statements, anywhere you need to
// dump a list into a readable format!
//
// HINT: extra credit: you can generalize this, and provide
// specialized short hands that invoke the general method
public static string ToCommaSeparatedString<T>(this IEnumerable<T> values)
{
// SIGH: so apparently this does not generate minimal
// assembler on every machine, please note the following
// is written for clarity, please feel free to substitute
// your own favourite ultra-performance high-octance
// string appender algorithm
StringBuilder commaSeparated = new StringBuilder ();
foreach (T value in values)
{
// PERF: store format string as const
commaSeparated.AppendFormat ("{0}, ", value);
}
// PERF: store trim chars as static readonly array
return commaSeparated.Trim (", ".ToCharArray ());
}
}
...
// elsewhere in code
List<int> myIdentifiers = new List<int> { 1, 2, 3, 4, 5, };
string mySqlIdentifierList = myIdentifiers.ToCommaSeparatedList ();
string mySqlStatementFormat = "SELECT * FROM [SomeTable] WHERE [Id] IN ({0})";
string mySqlStatement =
string.format (mySqlStatementFormat, mySqlIdentifierList);
...
公共静态类IEnumerableExtensions
{
//可以合理地假设您将在任何地方使用它,而不仅仅是
//Sql语句,但日志语句,您需要的任何位置
//将列表转储为可读格式!
//
//提示:额外学分:您可以概括这一点,并提供
//调用通用方法的专用短手
公共静态字符串到CommaseParatedString(此IEnumerable值)
{
//叹气:很明显,这并没有产生最小的
//每台机器上的装配工,请注意以下几点
//为清晰起见,请随意替换
//您最喜欢的超高性能高倍频
//字符串追加器算法
StringBuilder commaSeparated=新的StringBuilder();
foreach(值中的T值)
{
//性能:将格式字符串存储为常量
commaSeparated.AppendFormat(“{0},”,值);
}
//性能:将修剪字符存储为静态只读数组
返回逗号分隔的.Trim(“,”.tocharray());
}
}
...
//代码中的其他地方
List myIdentifiers=新列表{1、2、3、4、5、};
字符串mySqlIdentifierList=myIdentifiers.ToCommaSeparatedList();
string mySqlStatementFormat=“从[SomeTable]中选择*,其中[Id]位于({0})”中;
字符串mySqlStatement=
string.format(mySqlStatementFormat,mySqlIdentifierList);
...
您可以使用以下扩展方法更有效地执行此操作:
///<summary>Appends a list of strings to a StringBuilder, separated by a separator string.</summary>
///<param name="builder">The StringBuilder to append to.</param>
///<param name="strings">The strings to append.</param>
///<param name="separator">A string to append between the strings.</param>
public static StringBuilder AppendJoin(this StringBuilder builder, IEnumerable<string> strings, string separator) {
if (builder == null) throw new ArgumentNullException("builder");
if (strings == null) throw new ArgumentNullException("strings");
if (separator == null) throw new ArgumentNullException("separator");
bool first = true;
foreach (var str in strings) {
if (first)
first = false;
else
builder.Append(separator);
builder.Append(str);
}
return builder;
}
///<summary>Combines a collection of strings into a single string.</summary>
public static string Join<T>(this IEnumerable<T> strings, string separator, Func<T, string> selector) { return strings.Select(selector).Join(separator); }
///<summary>Combines a collection of strings into a single string.</summary>
public static string Join(this IEnumerable<string> strings, string separator) { return new StringBuilder().AppendJoin(strings, separator).ToString(); }
///将字符串列表附加到StringBuilder,并用分隔符字符串分隔。
///要附加到的StringBuilder。
///要追加的字符串。
///要在字符串之间追加的字符串。
公共静态StringBuilder AppendJoin(此StringBuilder、IEnumerable字符串、字符串分隔符){
如果(builder==null)抛出新的ArgumentNullException(“builder”);
如果(strings==null)抛出新的ArgumentNullException(“strings”);
如果(separator==null)抛出新的ArgumentNullException(“separator”);
bool first=true;
foreach(字符串中的var str){
如果(第一)
第一个=假;
其他的
builder.Append(分隔符);
附加(str);
}
返回生成器;
}
///将字符串集合合并为单个字符串。
公共静态字符串联接(此IEnumerable字符串、字符串分隔符、函数选择器){返回字符串。选择(选择器)。联接(分隔符);}
///将字符串集合合并为单个字符串。
公共静态字符串联接(此IEnumerable字符串,字符串分隔符){返回新的StringBuilder().AppendJoin(字符串,分隔符).ToString();}
//
///将整数数组转换为可在SQL in表达式中使用的字符串。
///
///要转换的数组。
///将数组表示为括号内逗号删除列表的字符串。如果数组
///为空或缺少,则返回“(null)”。
公共静态字符串ToSqlInList(int[]值)
{
如果(值==null | |值。长度==0)
return“(null)”;//在SQL中,表达式“In(null)”总是false。
返回string.Concat(“(”,string.Join(“,”,Array.ConvertAll(值,x=>x.ToString()),”);
}
如果整数列表很大,则可能生成的字符串太长,数据库无法接受。例如,我认为SQL2000中VARCHAR的最大长度约为8K
因此,我有一组助手方法,类似下面的示例,它返回字符串枚举,然后可以按如下方式使用:
List<int> idList = ...;
using(SqlCommand command = ...)
{
...
foreach(string idString in ConcatenateValues(ids,",", maxLength, false))
{
command.Parameters[...] = idString;
// or command.CommandText = "SELECT ... IN (" + idString + ")...";
... execute command ...
}
}
List idList=。。。;
使用(SqlCommand=…)
{
...
foreach(concatenateValue中的字符串idString(id,,,maxLength,false))
{
command.Parameters[…]=idString;
//或command.CommandText=“在(“+idString+”)中选择…”;
…执行命令。。。
}
}
连接方法可能如下所示:
public static IEnumerable<string> ConcatenateValues(IEnumerable<int> values, string separator, int maxLength, bool skipDuplicates)
{
IDictionary<int, string> valueDictionary = null;
StringBuilder sb = new StringBuilder();
if (skipDuplicates)
{
valueDictionary = new Dictionary<int, string>();
}
foreach (int value in values)
{
if (skipDuplicates)
{
if (valueDictionary.ContainsKey(value)) continue;
valueDictionary.Add(value, "");
}
string s = value.ToString(CultureInfo.InvariantCulture);
if ((sb.Length + separator.Length + s.Length) > maxLength)
{
// Max length reached, yield the result and start again
if (sb.Length > 0) yield return sb.ToString();
sb.Length = 0;
}
if (sb.Length > 0) sb.Append(separator);
sb.Append(s);
}
// Yield whatever's left over
if (sb.Length > 0) yield return sb.ToString();
}
public静态IEnumerable concatenateValue(IEnumerable值、字符串分隔符、int-maxLength、bool-skipDuplicates)
{
IDictionary valueDictionary=null;
StringBuilder sb=新的StringBuilder();
如果(skipDuplicates)
{
valueDictionary=新字典();
}
foreach(值中的int值)
{
如果(skipDuplicates)
{
如果(valueDictionary.ContainsKey(value))继续;
valueDictionary.Add(值“”);
}
字符串s=value.ToString(CultureInfo.InvariantCulture);
如果((sb长度+分隔符长度+s长度)>最大长度)
{
//已达到最大长度,生成结果并重新开始
如果(sb.Length>0)屈服,则返回sb.ToString();
sb.长度=0;
}
如果(sb.Length>0)sb.Append(分隔符);
某人追加;
}
//把剩下的都给我
如果(sb.Length>0)屈服,则返回sb.ToString();
}
将生成列表,而不是字符串
/// <summary>
/// Converts an array of integers into a string that may be used in a SQL IN expression.
/// </summary>
/// <param name="values">The array to convert.</param>
/// <returns>A string representing the array as a parenthetical comma-delemited list. If the array
/// is empty or missing, then "(null)" is returned.</returns>
public static string ToSqlInList(int[] values)
{
if (values == null || values.Length == 0)
return "(null)"; // In SQL the expression "IN (NULL)" is always false.
return string.Concat("(", string.Join(",", Array.ConvertAll<int, string>(values,x=>x.ToString())), ")");
}
List<int> idList = ...;
using(SqlCommand command = ...)
{
...
foreach(string idString in ConcatenateValues(ids,",", maxLength, false))
{
command.Parameters[...] = idString;
// or command.CommandText = "SELECT ... IN (" + idString + ")...";
... execute command ...
}
}
public static IEnumerable<string> ConcatenateValues(IEnumerable<int> values, string separator, int maxLength, bool skipDuplicates)
{
IDictionary<int, string> valueDictionary = null;
StringBuilder sb = new StringBuilder();
if (skipDuplicates)
{
valueDictionary = new Dictionary<int, string>();
}
foreach (int value in values)
{
if (skipDuplicates)
{
if (valueDictionary.ContainsKey(value)) continue;
valueDictionary.Add(value, "");
}
string s = value.ToString(CultureInfo.InvariantCulture);
if ((sb.Length + separator.Length + s.Length) > maxLength)
{
// Max length reached, yield the result and start again
if (sb.Length > 0) yield return sb.ToString();
sb.Length = 0;
}
if (sb.Length > 0) sb.Append(separator);
sb.Append(s);
}
// Yield whatever's left over
if (sb.Length > 0) yield return sb.ToString();
}