VS2008 включает объект контекстного меню "Add Service Reference", который создаст прокси для Вас негласно.
, Как был упомянут ранее, WCF не предназначается только как замена для типов веб-сервиса ASMX, но предоставлять последовательную, безопасную и масштабируемую методологию всем совместимым сервисам, является ли это по HTTP, tcp, именованным каналам или транспортам MSMQ.
я признаюсь, что у меня действительно есть другие проблемы с WCF (например, переписывающий сигнатуры методов, когда представление сервиса по basicHTTP - видит здесь , но в целом я думаю, что это - определенное улучшение
var inClause = "("
+ String.Join(",", values.Select(x => x.ToString()).ToArray())
+ ")";
Примечание : вам больше не нужно вызывать .ToArray ()
в .NET Framework 4. Новый String.Join
добавлен метод.
Вы можете использовать метод String.Join
, например:
var str = "(" + string.Join(", ", Array.ConvertAll(values, v => v.ToString(CultureInfo.InvariantCulture)));
Предполагая, что values
является массивом, Array.ConvertAll
должен быть более эффективным, чем LINQ с 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
Это тоже можно сделать в одной строке
public string ToInStatement(this int[] values) {
string[] stringValues =
Array.ConvertAll<int, string>(values, Convert.ToString);
string result = "(" + String.Join(",", stringValues) + ")";
return result;
}
You can do this more efficiently using the following extension method:
///<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(); }
Если у вас большой список целых чисел, вы можете создать строку, которая будет слишком длинной для вашей базы данных. Например, я думаю, что максимальная длина VARCHAR в SQL2000 составляет около 8 КБ.
Итак, у меня есть набор вспомогательных методов, подобных приведенному ниже примеру, которые возвращают перечисление строк, которые затем можно использовать следующим образом:
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();
}
Привет, отличные предложения, только небольшое изменение ниже
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);
...
/// <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())), ")");
}