Почему это не работает?
Прежде всего, я хотел бы начать с @Fredipux замечательных комментариев:
Эта структура GraphLayout описывает задачи и размер SSIS, расположение и размер компонентов. в Visual Studio SSIS Designer; макет определяется во время редактирования пакета. Когда пакет генерируется программно, макет конструктора не определяется, поскольку пакет создается вне VS Designer
Это верно !! Суть в том, что Microsoft.SqlServer.PipelineHost
, Microsoft.SqlServer.DTSPipelineWrap
, Microsoft.SqlServer.DTSRuntimeWrap
и Microsoft.SqlServer.ManagedDTS
являются оболочками. NET, которые позволяют создавать и выполнять пакеты программным образом, когда дизайн не имеет смысла. Если вы обращаетесь к официальной документации SSIS и просматриваете все разделы и подразделы, вы заметите, что упоминаются только эти три сборки, тогда как другие сборки, такие как Microsoft.SqlServer.IntegrationServices.Graph.dll
, не упоминаются, так как они связаны между собой. проектировщику Visual Studio.
Вы можете просто заметить, что четыре упомянутые сборки принадлежат пространству имен Microsoft.SqlServer.Dts
, а другая - Microsoft.SqlServer.IntegrationServices
.
Как упорядочить задачи в Visual Studio?
Обратите внимание, что в Visual Studio в полосе меню вы можете go до
Format >> Auto Layout >> Diagram
Тогда все задачи в потоке управления будут упорядочены .
В официальной документации я искал все свойства и методы, перечисленные для ManagedDTS и других. сборки, но я не нашел упомянутое, что вы можете использовать AutoLayout()
метод. Кроме того, я не нашел эту опцию доступной даже при использовании ezApi и BIML.
Кроме того, я попытался использовать обозреватель объектов Visual Studio для поиска этого метода без удачи.
Что-то попробуйте
Я думаю, что самый простой способ добавить макет - это создать предложение макета XML вручную (взять структуру XML, сформировать существующий пакет и изменить свойства Id, size и TopLeft) и добавить его. к пакету XML.
После запуска многих примеров это выглядит возможным, но очень сложным, когда имеется много связанных задач. В следующих подразделах я проиллюстрировал некоторую полезную информацию об узле GraphLayout
XML и о том, как добавить информацию с помощью сценария C#:
GraphLayout XML узел
Я пытался создайте консольное приложение, которое построило раздел макета XML и добавьте его в пакет. Но прежде чем показать код и эксперимент, я хотел бы проиллюстрировать некоторую информацию о Graphlayout XML.
Узел Graphlayout находится по следующему пути в XML:
DTS:DesignTimeProperties/Objects/Package/LayoutInfo/GraphLayout
Содержит проектную информацию обо всех объектах, добавленных в поток управления, даже в соединители с ограничениями предшествования. В этом XML узле вы можете найти три типа узлов (возможно, больше):
NodeLayout: которые описывают задачи, например:
<NodeLayout
Size="151,42"
Id="Package\Data Flow Task"
TopLeft="369,179" />
EdgeLayout: описывает соединители с ограничениями приоритета, и он более сложный, поскольку содержит всю информацию о кривых соединителей. Как пример:
<EdgeLayout
Id="Package.PrecedenceConstraints[Constraint]"
TopLeft="308.5,125">
<EdgeLayout.Curve>
<mssgle:Curve
StartConnector="{assembly:Null}"
EndConnector="136,54"
Start="0,0"
End="136,46.5">
<mssgle:Curve.Segments>
<mssgle:SegmentCollection
Capacity="5">
<mssgle:LineSegment
End="0,23" />
<mssgle:CubicBezierSegment
Point1="0,23"
Point2="0,27"
Point3="4,27" />
<mssgle:LineSegment
End="132,27" />
<mssgle:CubicBezierSegment
Point1="132,27"
Point2="136,27"
Point3="136,31" />
<mssgle:LineSegment
End="136,46.5" />
</mssgle:SegmentCollection>
</mssgle:Curve.Segments>
</mssgle:Curve>
</EdgeLayout.Curve>
<EdgeLayout.Labels>
<EdgeLabelCollection />
</EdgeLayout.Labels>
</EdgeLayout>
AnnotationLayout: которые описывают аннотации. Например:
<AnnotationLayout
Text="This is an annotation"
ParentId="Package"
FontInfo="{assembly:Null}"
Size="121,60"
Id="edef7a97-4253-4bb8-907e-6079f42467c6"
TopLeft="421,152" />
Эксперимент
Я создал консольное приложение, которое создает раздел DTS:DesignTimeProperties
вручную, без добавления информации о соединителях ограничений приоритета (так как это сложно) . Я только попытался добавить информацию о двух задачах, имеющих следующие идентификаторы:
- Выполнить T- SQL Задача оператора
- Задача потока данных
Эти задачи были связаны с помощью соединителя ограничения приоритета.
Я использовал следующий код для изменения файла пакета .dtsx:
class Program
{
static void Main(string[] args)
{
string package;
string xmlLayout = " <DTS:DesignTimeProperties><![CDATA[<?xml version=\"1.0\"?>\r\n" +
"<!--This CDATA section contains the layout information of the package. The section includes information such as (x,y) coordinates, width, and height.-->\r\n" +
"<!--If you manually edit this section and make a mistake, you can delete it. -->\r\n" +
"<!--The package will still be able to load normally but the previous layout information will be lost and the designer will automatically re-arrange the elements on the design surface.-->\r\n" +
" <Objects\r\n" +
" Version=\"8\">\r\n" +
" <!--Each node below will contain properties that do not affect runtime behavior.-->\r\n" +
" <Package\r\n" +
" design-time-name=\"Package\">\r\n" +
" <LayoutInfo>\r\n" +
" <GraphLayout\r\n" +
" Capacity=\"4\" xmlns=\"clr-namespace:Microsoft.SqlServer.IntegrationServices.Designer.Model.Serialization;assembly=Microsoft.SqlServer.IntegrationServices.Graph\" xmlns:mssgle=\"clr-namespace:Microsoft.SqlServer.Graph.LayoutEngine;assembly=Microsoft.SqlServer.Graph\" xmlns:assembly=\"http://schemas.microsoft.com/winfx/2006/xaml\">";
xmlLayout += "\r\n" + AddNodeLayout("Execute T-SQL Statement Task", 193, 83);
xmlLayout += "\r\n" + AddNodeLayout("Data Flow Task", 369, 179);
xmlLayout += "\r\n" + " </GraphLayout>\r\n" +
" </LayoutInfo>\r\n" +
" </Package>\r\n" +
"</Objects>]]></DTS:DesignTimeProperties>\r\n";
using (System.IO.StreamReader sr = new System.IO.StreamReader(@"G:\SSIS_Test\Integration Services Project1\Package3.dtsx"))
{
package = sr.ReadToEnd();
sr.Close();
}
package = package.Substring(0, package.LastIndexOf("</DTS:Executable>")) +
xmlLayout + package.Substring(package.LastIndexOf("</DTS:Executable>"));
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(@"G:\SSIS_Test\Integration Services Project1\Package3.dtsx"))
{
sw.Write(package);
sw.Close();
}
}
static string AddNodeLayout(string TaskId, int x, int y)
{
return " <NodeLayout\r\n" +
" Size=\"225,42\"\r\n" +
" Id=\"Package\\" + TaskId + "\"\r\n" +
" TopLeft=\"" + x.ToString() + "," + y.ToString() + "\" />";
}
}
Результаты и обсуждение
Раздел был добавлен успешно, но это не имеет смысла при открытии пакета в Visual Studio, поскольку задачи не были организованы, как описано (AutoLayout () был выполнен Visual Studio)
Я попытался удалить соединитель между обеими задачами и перезапустить эксперимент, задачи были организованы успешно:
Это означает, что если какой-либо макет объектов задач не определен, Visual Studio проигнорирует добавленный раздел и выполнит функцию AutoLayout () при открытии пакета.
На основании этого, если вы решили go При таком подходе (или даже при любом другом подходе) вы должны знать, как можно генерировать EdgeLayout
узлы.
Обновление - поиск метода AutoLayout ()
Основываясь на ваших комментариях, вы не хотите добавлять каждое местоположение задачи вручную, но вы хотите выполнить метод AutoLayout()
.
После проверки сборок, импортированных в ваш проект, я провел небольшой поиск, используя Обозреватель объектов для метода AutoLayout()
. Я думаю, что найдено два соответствующих метода:
Microsoft.SqlServer.IntegrationServices.Designer.View.BaseGraphControl.AutoLayout()
Microsoft.SqlServer.IntegrationServices.Designer.View.IGraphControlEx.AutoLayout()
Я не знаю, могут ли они быть выполнены из C# скрипт, так как они не принимают никаких аргументов. Я думаю, что они не созданы для использования из сценария C#, но являются внутренними методами для Visual studio. Но вы можете попробовать.
Примечание. По моему мнению, выполнение этого метода программно бесполезно, поскольку он будет выполняться Visual Studio после открытия пакета и не повлияет на выполнение пакета вообще