I'm working on a C# application to generate the script. I have the following settings below, but tables/insert statements are being generated for other schemas. I just want one specific schema and all the schema/data from it.
I tried to set options.WithDependencies = false;, but then it wouldn't give me everything I needed as in scripting the data.
What other setting am I missing?
private void GeneratingMainSQLScript(string schema)
{
Server srv = new Server(#".\sql2017");
Database dbs = srv.Databases["SOURCE_T"];
ScriptingOptions options = new ScriptingOptions();
options.TargetServerVersion = SqlServerVersion.Version140;
options.EnforceScriptingOptions = true;
options.ScriptData = true;
options.ScriptDrops = false;
options.FileName = GenerateScriptFileName(schema, false);
options.EnforceScriptingOptions = true;
options.ScriptSchema = true;
options.IncludeHeaders = true;
options.AppendToFile = true;
options.Indexes = true;
options.WithDependencies = true;
var tableNames = GetTableNames(schema);
int progressCounter = 1;
foreach (var tbl in tableNames)
{
if (tbl.SchemaName == "dbo" && tbl.TableName == "FileDatas")
{
options.ScriptData = false;
}
dbs.Tables[tbl.TableName, tbl.SchemaName].EnumScript(options);
DisplayDebug(string.Format("Running migration schema's ({2}) main genreated script | Total: {0} | Processing #: {1}", tableNames.Count, progressCounter, schema));
progressCounter++;
}
}
UPDATE:
I made these changes after working with my lead and we are close. The issue now: it is generating the FKS after creating the table and not at the END of the file like when you do it via SSMS directly?
Server srv = new Server(#".\sql2017");
Database dbs = srv.Databases["SOURCE_T"];
ScriptingOptions options = new ScriptingOptions();
options.FileName = GenerateScriptFileName(schema, isSchemaOnly);
options.EnforceScriptingOptions = true;
// start
options.AnsiPadding = false;
options.AppendToFile = true;
options.ContinueScriptingOnError = false;
options.ConvertUserDefinedDataTypesToBaseType = false;
options.WithDependencies = false;
options.IncludeHeaders = true;
options.IncludeScriptingParametersHeader = false;
options.SchemaQualify = true;
options.Bindings = false;
options.NoCollation = true;
options.Default = true;
options.ScriptDrops = false;
options.ScriptSchema = isSchemaOnly;
options.ExtendedProperties = true;
options.TargetServerVersion = SqlServerVersion.Version140;
options.TargetDatabaseEngineType = Microsoft.SqlServer.Management.Common.DatabaseEngineType.Standalone;
options.LoginSid = false;
options.Statistics = false;
options.ScriptData = !isSchemaOnly;
options.ChangeTracking = false;
options.DriAllConstraints = true;
options.ScriptDataCompression = false;
options.DriForeignKeys = true;
options.FullTextIndexes = false;
options.Indexes = false;
options.DriPrimaryKey = true;
options.Triggers = false;
options.DriUniqueKeys = true;
options.DriAll = true;
Here is the solution I am using. The key here is all the options that I have set, but also how I pull the table names. GetTablesNames will obtain the tables in the order that they need to be made in, which allows for everything to process properly along with the FKs.
Obtaining the tables properly
setting this variable to false: options.WithDependencies = false;
Are the keys to my solution.
private void GeneratingMainSQLScript(string schema, bool isSchemaOnly)
{
Server srv = new Server(sqlServer);
Database dbs = srv.Databases["SOURCE_T"];
ScriptingOptions options = new ScriptingOptions();
options.FileName = GenerateScriptFileName(schema, isSchemaOnly);
options.EnforceScriptingOptions = true;
// start
options.AnsiPadding = false;
options.AppendToFile = true;
options.ContinueScriptingOnError = false;
options.ConvertUserDefinedDataTypesToBaseType = false;
options.WithDependencies = false;
options.IncludeHeaders = true;
options.IncludeScriptingParametersHeader = false;
options.SchemaQualify = true;
options.Bindings = false;
options.NoCollation = true;
options.Default = true;
options.ScriptDrops = false;
options.ScriptSchema = true;
options.ExtendedProperties = true;
options.TargetServerVersion = SqlServerVersion.Version140;
options.TargetDatabaseEngineType = Microsoft.SqlServer.Management.Common.DatabaseEngineType.Standalone;
options.LoginSid = false;
options.Statistics = false;
options.ScriptData = true;
options.ChangeTracking = false;
options.DriAllConstraints = true;
options.ScriptDataCompression = false;
options.DriForeignKeys = true;
options.FullTextIndexes = false;
options.Indexes = false;
options.DriPrimaryKey = true;
options.Triggers = false;
options.DriUniqueKeys = true;
if (isSchemaOnly == true)
{
options.ScriptSchema = true;
options.DriForeignKeys = true;
options.SchemaQualify = true;
options.SchemaQualifyForeignKeysReferences = true;
options.DriAll = true;
options.ScriptData = false;
}
else
{
options.ScriptSchema = false;
options.ScriptData = true;
options.DriAll = false;
}
var tableNames = GetTablesNames(schema, sourceDefaultConnection, true);
int progressCounter = 1;
foreach (var tbl in tableNames)
{
if (tbl.SchemaName == "HR" && tbl.TableName == "FileDatas" && isSchemaOnly == false)
{
continue;
}
else
{
dbs.Tables[tbl.TableName, tbl.SchemaName].EnumScript(options);
}
DisplayDebug(string.Format("Running migration schema's ({2}) main generated script | Total: {0} | Processing #: {1}", tableNames.Count, progressCounter, schema));
progressCounter++;
}
}
private IList<DatabaseTableDTO> GetTablesNames(string schema, string connectionName, bool isAscending)
{
string sql = string.Format(#"WITH cte (lvl, object_id, name, schema_Name) AS
(SELECT 1, object_id, sys.tables.name, sys.schemas.name as schema_Name
FROM sys.tables Inner Join sys.schemas on sys.tables.schema_id = sys.schemas.schema_id
WHERE type_desc = 'USER_TABLE'
AND is_ms_shipped = 0
UNION ALL SELECT cte.lvl + 1, t.object_id, t.name, S.name as schema_Name
FROM cte
JOIN sys.tables AS t ON EXISTS
(SELECT NULL FROM sys.foreign_keys AS fk
WHERE fk.parent_object_id = t.object_id
AND fk.referenced_object_id = cte.object_id )
JOIN sys.schemas as S on t.schema_id = S.schema_id
AND t.object_id <> cte.object_id
AND cte.lvl < 30
WHERE t.type_desc = 'USER_TABLE'
AND t.is_ms_shipped = 0 )
SELECT schema_Name, name, MAX (lvl) AS dependency_level
FROM cte
where schema_Name = '{0}'
GROUP BY schema_Name, name
ORDER BY dependency_level {1},schema_Name, name;", schema, isAscending == true ? "ASC" : "DESC");
var connectionString = ConfigurationManager.ConnectionStrings[connectionName];
var listOfTables = new List<DatabaseTableDTO>();
using (SqlConnection conn = new SqlConnection(connectionString.ConnectionString))
{
conn.Open();
using (var command = new SqlCommand(sql, conn))
{
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
listOfTables.Add(new DatabaseTableDTO { SchemaName = schema, TableName = reader.GetString(1) });
}
}
}
}
return listOfTables;
}
public class DatabaseTableDTO
{
public string SchemaName { get; set; }
public string TableName { get; set; }
}
Related
I tried to set some of the settings such as Compact =false, CompactData = false, etc but nothing worked.
I wanted to separate the "Reviewer and Engagement instead of them in one field. I have posted two photos. The first is the output I have, Second is the one that I am trying to achieve.
enter code
//define the data range on the source sheet
var dataRange = workSheetDataSource.Cells[workSheetDataSource.Dimension.Address];
//create the pivot table
var pivotTable = workSheetMgrAndEng.PivotTables.Add(workSheetMgrAndEng.Cells["A4"], dataRange, "PivotTable");
//label field
pivotTable.RowFields.Add(pivotTable.Fields["Reviewer"]);
pivotTable.RowFields.Add(pivotTable.Fields["Engagement"]);
//pivot field settings
pivotTable.Compact = false;
pivotTable.CompactData = false;
pivotTable.Indent = 0;
//pivotTable.RowGrandTotals = false;
pivotTable.UseAutoFormatting = true;
//pivotTable.ShowMemberPropertyTips = false;
pivotTable.DataOnRows = false;
//data fields
var field1 = pivotTable.DataFields.Add(pivotTable.Fields["Engagement"]);
field1.Name = "Count of Engagement";
field1.Function = DataFieldFunctions.Count;
var field2 = pivotTable.DataFields.Add(pivotTable.Fields["Prep Complete"]);
field2.Name = "Count of Prep Complete";
field2.Function = DataFieldFunctions.Count;
var field3 = pivotTable.DataFields.Add(pivotTable.Fields["Sent Delivered"]);
field3.Name = "Sent/Delivered";
field3.Function = DataFieldFunctions.Count;
var field4 = pivotTable.DataFields.Add(pivotTable.Fields["Return to Tax Office"]);
field4.Name = "Count of Return to Tax Office";
field4.Function = DataFieldFunctions.Count;
//data fields settings
//field1.Field.Outline = false;
field1.Field.Compact = false;
field1.Field.ShowAll = false;
//field1.Field.SubtotalTop = false;
//field2.Field.Outline = false;
field2.Field.Compact = false;
field2.Field.ShowAll = false;
//field2.Field.SubtotalTop = false;
//field3.Field.Outline = false;
field3.Field.Compact = false;
field3.Field.ShowAll = false;
//field3.Field.SubtotalTop = false;
//field4.Field.Outline = false;
field4.Field.Compact = false;
field4.Field.ShowAll = false;
//field4.Field.SubtotalTop = false;
I try to generate a script which is contains datas in INSERT script forms,
I try to use a reference (see below) to do it
using Microsoft.SqlServer.Management.Smo;
with this code draft
Server serv = new Server(db);
Database simba = serv.Databases[dbname];
string script = "";
ScriptingOptions so = new ScriptingOptions()
{
ScriptData = true,
ScriptSchema = false,
ScriptDrops = false
};
foreach (Table tb in simba.Tables)
{
if (tables.Contains(tb.Name))
{
var sc = tb.Script(so);
foreach (var s in sc)
script += s;
}
using (StreamWriter writer = new StreamWriter(file))
{
foreach (string tab in tables)
writer.WriteLine(script);
}
}
but this code get an error on
var sc = tb.Script(so);
which is
Microsoft.SqlServer.Management.Smo.FailedOperationException
thanks for all reply
I have this code and it is working fine try to use it
var report = string.Empty;
var fileName = Server.MapPath(Constants.BACKUP_FILE_NAME);
var server = new Server(new ServerConnection(new SqlConnection(Constants.BACKUP_CONNECTION_STRING)));
var options = new ScriptingOptions();
var databases = server.Databases[Constants.BACKUP_DATABASE_NAME];
options.FileName = fileName;
options.EnforceScriptingOptions = true;
options.WithDependencies = true;
options.IncludeHeaders = true;
options.ScriptDrops = false;
options.AppendToFile = true;
options.ScriptSchema = true;
options.ScriptData = true;
options.Indexes = true;
report = "<h4>Table Scripts</h4>";
foreach (var table in Constants.BACKUP_TABLES)
{
databases.Tables[table, Constants.BACKUP_SCHEMA_NAME].EnumScript(options);
report += "Script Generated: " + table + "<br>";
}
The "Constants" is my class to hold the constant values like file name, db etc and I am generating script for limited tables so for that reason not doing "simba.Tables" like you have done in your code; you can surely do that if you want every table scripts to be generated. So this code generates script and store it to specified file.
Hope it helps
Thanks #Zaki Mohammed,
Your code helped me a lot,
I just modify a bit for my case and it works perfectly,
Server serv = new Server(db);
Database simba = serv.Databases[dbname];
Scripter scripter = new Scripter(serv);
scripter.Options.FileName = "InsertIntoScript.sql";
scripter.Options.EnforceScriptingOptions = true;
scripter.Options.WithDependencies = false;
scripter.Options.IncludeHeaders = true;
scripter.Options.ScriptDrops = false;
scripter.Options.AppendToFile = true;
scripter.Options.ScriptSchema = false;
scripter.Options.ScriptData = true;
scripter.Options.Indexes = false;
string script = "";
foreach (Table tb in simba.Tables)
{
if (tables.Contains(tb.Name))
{
IEnumerable<string> sc = scripter.EnumScript(new Urn[] { tb.Urn });
foreach (var s in sc)
script += s;
}
}
I am using Visual Studio 2015 and Entity Framework 6. I am trying to add entries from inputted information into multiple tables.
This is what I have so far:
protected void btnOrder_Click(object sender, EventArgs e)
{
using (FlowerCompanyEntities flower = new FlowerCompanyEntities())
{
int rFlowers = 0;
Boolean rVase = false;
DateTime DeliveryDate = DateTime.Parse(tbDelivery.Text);
string flowerArrangement = ddlListFlowers.SelectedValue;
if (flowerArrangement == "f2")
{
rFlowers = 1;
}
if (flowerArrangement == "f3")
{
rFlowers = 2;
}
if (flowerArrangement == "f1")
{
rFlowers = 3;
}
if (flowerArrangement == "f4")
{
rFlowers = 4;
}
if (flowerArrangement == "f5")
{
rFlowers = 5;
}
string vase = rbList.SelectedItem.Value.ToString();
if (vase == "NO")
{
rVase = false;
}
if (vase == "YES")
{
rVase = true;
}
Customers cust = new Customers();
Addresses Addr = new Addresses();
Phone Pho = new Phone();
Delivery Del = new Delivery();
Arrangements arr = new Arrangements();
OrderStatus ordstat = new OrderStatus();
Orders ord = new Orders();
Pho.Phone1 = tbPhone.Text;
Addr.Street = tbStreet.Text;
Addr.City = tbCity.Text;
Addr.States = tbState.Text;
Addr.Zip = tbZip.Text;
cust.FirstName = tbFirstName.Text;
cust.LastName = tbLastName.Text;
Del.DeliverDate = DeliveryDate;
arr.FlowerID = rFlowers;
ordstat.OrderStatus1 = tbStatus.Text;
ord.Vase = rVase;
ord.OrderMessage = tbOrderMessage.Text;
try {
flower.Phone.Add(Pho);
flower.Addresses.Add(Addr);
flower.Customers.Add(cust);
flower.Delivery.Add(Del);
flower.Arrangements.Add(arr);
flower.OrderStatus.Add(ordstat);
flower.Orders.Add(ord);
flower.SaveChanges();
Response.Redirect("Orders.aspx");
}
catch { }
}
However, on the button click i get an exception error. I also just realized that some of those tables -- with those entries would need the foreign key of the other tables put in.
Question: How do I add all these entries to my database when there is multiple tables and foreign keys?
I have created a hierarchical relationship in a RadGridView. But the relationship doesn't work. I can't show the detail information. What do I do wrong?
If I generated automatically all relationships works fine. But I need just one field of one table as detail info.
Further: I use VS2013 Prof., WinForms as UI and LINQ to SQL as datasource.
The source code is:
private void OpenConfigurations()
{
bsConfigurations.DataSource = Db.Configurations.Where(c => c.Active == true && c.CompanyId == CurrentCompany.CompanyId).Select(c => c).OrderBy(c => c.Name);
bsConfigurationContracts.DataSource = Db.ConfigurationContracts.Where(c => c.Contract.InsurranceId == CurrentCompany.CompanyId).Select(c =>
c).OrderBy(c => c.Contract.Name);
GridViewRelation gvrConfigurations = new GridViewRelation();
gvrConfigurations.ChildColumnNames.Add("ConfigurationId");
gvrConfigurations.ChildTemplate = this.gridViewTemplate1;
gvrConfigurations.ParentColumnNames.Add("ConfigurationId");
gvrConfigurations.ParentTemplate = this.gvConfiguration.MasterTemplate;
gvConfiguration.Relations.Add(gvrConfigurations);
}
In the designer:
this.gridViewTemplate1.AllowAddNewRow = false;
gridViewTextBoxColumn1.EnableExpressionEditor = false;
gridViewTextBoxColumn1.FieldName = "Contract.Name";
gridViewTextBoxColumn1.HeaderText = "Name";
gridViewTextBoxColumn1.Name = "colName";
gridViewTextBoxColumn1.Width = 250;
gridViewTextBoxColumn2.EnableExpressionEditor = false;
gridViewTextBoxColumn2.FieldName = "ConfigurationId";
gridViewTextBoxColumn2.HeaderText = "ConfigurationId";
gridViewTextBoxColumn2.IsVisible = false;
gridViewTextBoxColumn2.Name = "colConfigurationId";
this.gridViewTemplate1.Columns.AddRange(new Telerik.WinControls.UI.GridViewDataColumn[] { gridViewTextBoxColumn1, gridViewTextBoxColumn2 });
this.gridViewTemplate1.DataSource = this.bsConfigurationContracts;
//
// gvConfiguration
//
this.gvConfiguration.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(233)))), ((int)(((byte)(240)))), ((int)(((byte)(249)))));
this.gvConfiguration.Cursor = System.Windows.Forms.Cursors.Default;
this.gvConfiguration.Dock = System.Windows.Forms.DockStyle.Fill;
this.gvConfiguration.Font = new System.Drawing.Font("Segoe UI", 8.25F);
this.gvConfiguration.ForeColor = System.Drawing.Color.Black;
this.gvConfiguration.ImeMode = System.Windows.Forms.ImeMode.NoControl;
this.gvConfiguration.Location = new System.Drawing.Point(0, 30);
//
//
//
this.gvConfiguration.MasterTemplate.AllowAddNewRow = false;
this.gvConfiguration.MasterTemplate.AutoGenerateColumns = false;
gridViewTextBoxColumn3.EnableExpressionEditor = false;
gridViewTextBoxColumn3.FieldName = "Name";
gridViewTextBoxColumn3.HeaderText = "Name";
gridViewTextBoxColumn3.Name = "colName";
gridViewTextBoxColumn3.SortOrder = Telerik.WinControls.UI.RadSortOrder.Ascending;
gridViewTextBoxColumn3.Width = 250;
gridViewTextBoxColumn4.EnableExpressionEditor = false;
gridViewTextBoxColumn4.FieldName = "ConfigurationId";
gridViewTextBoxColumn4.HeaderText = "ConfigurationId";
gridViewTextBoxColumn4.IsVisible = false;
gridViewTextBoxColumn4.Name = "colConfigurationId";
this.gvConfiguration.MasterTemplate.Columns.AddRange(new Telerik.WinControls.UI.GridViewDataColumn[] { gridViewTextBoxColumn3, gridViewTextBoxColumn4 });
this.gvConfiguration.MasterTemplate.DataSource = this.bsConfigurations;
sortDescriptor1.PropertyName = "colName";
this.gvConfiguration.MasterTemplate.SortDescriptors.AddRange(new Telerik.WinControls.Data.SortDescriptor[] { sortDescriptor1 });
this.gvConfiguration.MasterTemplate.Templates.AddRange(new Telerik.WinControls.UI.GridViewTemplate[] { this.gridViewTemplate1 });
this.gvConfiguration.Name = "gvConfiguration";
this.gvConfiguration.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.gvConfiguration.ShowGroupPanel = false;
this.gvConfiguration.Size = new System.Drawing.Size(1098, 72);
this.gvConfiguration.TabIndex = 4;
this.gvConfiguration.Text = "radGridView1";
this.gvConfiguration.CellDoubleClick += new Telerik.WinControls.UI.GridViewCellEventHandler(this.gvConfiguration_CellDoubleClick);
The solution is in the relation you have to add the column name in stead of the field name.
So this is the right code:
GridViewRelation gvrConfigurations = new GridViewRelation();
gvrConfigurations.ChildColumnNames.Add("colConfigurationId");
gvrConfigurations.ChildTemplate = this.gridViewTemplate1;
gvrConfigurations.ParentColumnNames.Add("colConfigurationId");
gvrConfigurations.ParentTemplate = this.gvConfiguration.MasterTemplate;
gvConfiguration.Relations.Add(gvrConfigurations);
So to try and give you an idea of what im working with, I have two drop down boxes. The first drop down box has a list of 4 Applications. The second drop down box changes dynamically with my selection in the first drop down box. I have a chart for each selection in the second drop down box. I have 16 charts total. Each time i change the second selection, the chart changes so that there is only one chart showing at a time. Im using if else statements and it has become way to hard to keep up with. I also have labels that i have to toggle with each chart so its getting out of control. Here is a small example of one of my else if statements.
else if (ddlApplication.SelectedItem.Text == "Rapp" && ddlTests.SelectedItem.Text == "Total Test Runs")
{
string query = string.Format("select TestName,Count (TestName) AS Counts from VExecutionGlobalHistory where TestTypeID = 2 group by TestName", ddlTests.SelectedItem.Value);
DataTable dt = GetData(query);
//Loop and add each datatable row to the Pie Chart Values
foreach (DataRow row in dt.Rows)
{
SpecificTestsRapp.PieChartValues.Add(new AjaxControlToolkit.PieChartValue
{
Category = row["TestName"].ToString(),
Data = Convert.ToDecimal(row["Counts"])
});
}
string SpecificTestsRappS = null;
string sql2 = "select Count (TestName) AS Counts from VExecutionGlobalHistory where TestTypeID = 2 ";
string connString2 = ";Initial Catalog=Performance;User ID=;Password=";
using (SqlConnection conn = new SqlConnection(connString2))
{
conn.Open();
using (SqlCommand command = new SqlCommand(sql2, conn))
{
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
SpecificTestsRappS = reader[0].ToString();
lblTotalTestsRapp.Text = SpecificTestsRappS;
break;
}
}
conn.Close();
}
SpecificTestsRapp.ChartTitle = "Total Tests Run";
TotalTestsWeb6.Visible = false;
HoursWeb6.Visible = false;
TotalValidationsWeb6.Visible = false;
CostComparisonWeb6.Visible = false;
SpecificTestsWeb6.Visible = false;
TotalTestsRapp.Visible = false;
TotalValidationsRapp.Visible = false;
SpecificTestsRapp.Visible = true;
HoursRapp.Visible = false;
IONChart.Visible = false;
CostComparisonRapp.Visible = false;
txtTotalHoursRapp.Visible = false;
lblTotalHoursRapp.Visible = false;
txtTotalHoursRappA.Visible = false;
lblTotalHoursRappA.Visible = false;
txtTotalCostRappM.Visible = false;
lblTotalCostRappM.Visible = false;
txtTotalCostRappA.Visible = false;
lblTotalCostRappA.Visible = false;
txtTotalTestsRapp.Visible = true;
lblTotalTestsRapp.Visible = true;
lblTotalValidationsRapp.Visible = false;
txtTotalValidationsRapp.Visible = false;
lblTotalValidations.Visible = false;
txtTotalValidations.Visible = false;
lblTotalTests.Visible = false;
txtTotalTests.Visible = false;
txtTotalHours.Visible = false;
lblTotalHours.Visible = false;
txtTotalHoursA.Visible = false;
lblTotalHoursA.Visible = false;
txtTotalCostA.Visible = false;
lblTotalCostA.Visible = false;
txtTotalCostM.Visible = false;
lblTotalCostM.Visible = false;
Label1.Visible = false;
Label2.Visible = false;
}
Technically i will need 16 of these when im done since i have 16 charts. There has to be a more efficient way to do this. Any suggestions?
I'm thinking Startegy and Factory design patterns.
You could do something in the lines of:
In your UI:
var chartStartegyFactory = new ChartStrategyFactory();
var chartStategy = chartStartegyFactory.Create(ddlApplication.SelectedItem.Text, ddlTests.SelectedItem.Text);
var chart = chartStategy.CreateChart();
lblTotalTestsRapp.Text = chart.ChartData;
SpecificTestsRapp.ChartTitle = chart.ChartTitle;
TotalTestsWeb6.Visible = chart.TotalTestsWeb6Visible;
// continue assigning properties in your UI
In your business layer:
public class ChartStrategyFactory
{
public IChartStrategy Create(string application, string test)
{
if (application == "Rapp" && test == "Total Test Runs")
return new RappTotalTestsRunChartStrategy();
// add strategies for other charts
throw new NotSupportedException();
}
}
public interface IChartStrategy
{
Chart CreateChart();
}
public class Chart
{
public string ChartTitle { get; set; }
public string ChartData { get; set; }
public bool TotalTestsWeb6Visible { get; set; }
// create all properties you need
}
public class RappTotalTestsRunChartStrategy : IChartStrategy
{
public Chart CreateChart(){
Chart chart = new Chart();
chart.ChartData = GetDataFromDatabase();
chart.ChartTitle = "Your Chart Title";
chart.TotalTestsWeb6Visible = false;
// continue assigning properties
return chart;
}
}
Basically your Chart creation code will be encapsulated in each Startegy and you will gain extensibility (it suffices to modify your ChartStrategyFactory when a new chart is developed.