TLDR : не изобретать велосипед, использовать существующие алгоритмы и структуры.
Я предполагаю, что ваш вопрос не о тренировочном упражнении, а о реальной проблеме. Если это упражнение, постарайтесь получить хорошее представление о рекурсии на простом в использовании языке по вашему выбору в большом сообществе, прежде чем вернуться к x ++.
Ваш метод рекурсии выглядит неполным, потому что в каждой рекурсии вы перебираете все записи из tmpBom
, что (если вы не измените записи в этой таблице где-то еще) не имеет смысла и никогда не завершится. Я также не понимаю, как этот метод может дать результат, который вы описываете. Я предлагаю вам взглянуть на некоторые учебные материалы по алгоритму рекурсии, чтобы узнать об основных частях рекурсии.
Вы отметили вопрос x ++ , и синтаксис также очень похож на этот. К сожалению, вы не добавили информацию о том, какую версию microsoft-Dynamics вы используете, но я предполагаю Dynamics-Ax-2012 , поскольку в настоящее время это самая распространенная версия в использовании. [ 118]
В этой версии уже есть готовый отчет SSRS, который покажет вам структуру ведомости материалов. Вы можете вызвать отчет в Управление запасами> Отчеты> Спецификации> Строки . Следует довольно легко изменить этот отчет, чтобы он также отображал уровень, если отчет еще не удовлетворяет вашим требованиям.
Если вам все еще нужно реализовать собственное решение, взгляните на класс BOMSearch
и его детей. Он используется в нескольких местах (проверьте перекрестные ссылки), а также может использоваться для расширения / взрыва спецификации.
Также обратите внимание, что есть много статей, которые пытаются объяснить, как расширить или взорвать спецификацию в коде x ++, но, как и во всех вещах в Интернете, будьте осторожны: большинство из них неполные или простые неправильно.
WebGetAttribute
поставляется Microsoft, и я не думаю, что вы можете расширить WebMessageFormat
. Однако вы, вероятно, могли бы расширить WebHttpBinding
, который использует WebGetAttribute
. Вы можете добавить свой собственный атрибут, например
[WebGet2(UriTemplate = "foo", ResponseFormat = WebMessageFormat2.PlainText)]
string Foo();
. Как правило, настройка макета сообщения в WCF называется настраиваемым кодировщиком / кодировкой сообщений. Microsoft предоставляет пример: Пользовательский кодировщик сообщений: кодировщик сжатия . Еще одно распространенное расширение, которое делают люди, - это расширение поведения, добавляющее настраиваемую обработку ошибок, чтобы вы могли поискать какой-нибудь пример в этом направлении.
Вы можете добавить свой собственный атрибут, например[WebGet2(UriTemplate = "foo", ResponseFormat = WebMessageFormat2.PlainText)]
string Foo();
. Как правило, настройка макета сообщения в WCF называется настраиваемым кодировщиком / кодировкой сообщений. Microsoft предоставляет пример: Пользовательский кодировщик сообщений: кодировщик сжатия . Еще одно распространенное расширение, которое делают люди, - это расширение поведения, добавляющее настраиваемую обработку ошибок, чтобы вы могли поискать какой-нибудь пример в этом направлении.
Вы можете добавить свой собственный атрибут, например[WebGet2(UriTemplate = "foo", ResponseFormat = WebMessageFormat2.PlainText)]
string Foo();
. Как правило, настройка макета сообщения в WCF называется настраиваемым кодировщиком / кодировкой сообщений. Microsoft предоставляет пример: Пользовательский кодировщик сообщений: кодировщик сжатия . Еще одно распространенное расширение, которое делают люди, - это расширение поведения, добавляющее настраиваемую обработку ошибок, чтобы вы могли поискать какой-нибудь пример в этом направлении.
Попробуйте использовать
BodyStyle = WebMessageBodyStyle.Bare
Затем верните System.IO.Stream из вашей функции.
Вот некоторый код, который я использую, чтобы вернуть изображение из базы данных, но доступный через URL:
[OperationContract()]
[WebGet(UriTemplate = "Person/{personID}/Image", BodyStyle = WebMessageBodyStyle.Bare)]
System.IO.Stream GetImage(string personID);
Реализация:
public System.IO.Stream GetImage(string personID)
{
// parse personID, call DB
OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse;
if (image_not_found_in_DB)
{
context.StatusCode = System.Net.HttpStatusCode.Redirect;
context.Headers.Add(System.Net.HttpResponseHeader.Location, url_of_a_default_image);
return null;
}
// everything is OK, so send image
context.Headers.Add(System.Net.HttpResponseHeader.CacheControl, "public");
context.ContentType = "image/jpeg";
context.LastModified = date_image_was_stored_in_database;
context.StatusCode = System.Net.HttpStatusCode.OK;
return new System.IO.MemoryStream(buffer_containing_jpeg_image_from_database);
}
В вашем случае, чтобы вернуть необработанная строка, установите ContentType на что-то вроде «text / plain» и возвращайте ваши данные в виде потока. В предположении, что-то вроде этого:
return new System.IO.MemoryStream(ASCIIEncoding.Default.GetBytes(string_to_send));
Есть один способ, как этого добиться, если вы имеете дело с HTTP, это не совсем хорошо, но я подумал, что могу это упомянуть.
Вы можете установить тип возвращаемого значения вашего метода void и просто выводить необработанную строку непосредственно в ответ.
[OperationContract]
[WebGet(UriTemplate = "foo")]
void Foo()
{
HttpContext.Current.Response.Write("bar");
}