New or Changed APIs
Last Updated: June 2020
This document lists the new or changed APIs in the following NuGet packages:
NuGet Package | Release | Product Bundle |
---|---|---|
SnapObjects .NET DataStore PowerScript Migrator Framework |
2.1.0 2.1.0 1.0.2 |
RapidSharp 2019 R2 |
SnapObjects .NET DataStore PowerScript Migrator Framework |
2.0.0 2.0.0 1.0.1 |
PowerBuilder 2019 R2 |
PowerScript Migrator Framework
1.0.2
1.0.2 has the following API changes:
- The GetBlocks and SetBlocks methods of DataStoreExtensions have been renamed to GetBlock and SetBlock.
- Extension methods under PbGlobal have been moved, for example, extension methods for string have been moved from PbGlobal to StringExtensions (likewise, BooleanExtensions, DateTimeExtensions, PbBlobExtensions, TimeSpanExtensions).
1.0.1
DataObject moved from DwNet.Data to PowerScript.Bridge
DataObject has been moved from DwNet.Data to PowerScript.Bridge; but data-related properties such as Table and its dependent objects are still preserved in DwNet.Data. When using DataObject, you will need to add the PowerScript.Bridge namepspace as below:
using PowerScript.Bridge;
For more about DataObject, refer to DataObject in PowerScript Bridge API Reference.
SnapObjects
2.1.0
2.1.0 has the following API changes:
- The IDataContextOptions interface has two new properties: DelimitIdentifier and TrimSpaces.
- The ConnectionString property of the IDataContextOptions interface is changed from {get; set;} to {get;}.
- The OracleDataContextOptions class has a new property: InitialLongFetchSize.
- New extension methods have been added to IDataContextOptions<T> for the supported database types.
2.0.0
SqlModelMapper supports to track DataStore
SqlModelMapper supports to track DataStore, so DataStore can be managed by SqlModelMapper transaction management.
var dataStore = new DataStore("d_emp", _context);
dataStore.Retrieve();
dataStore.SetItem(0, "name", "leo");
context.SqlModelMapper.Track(dataStore, false);
var result =context.SqlModelMapper.SaveChanges();
For detailed instructions on how to track actions with SqlModelMapper, refer to to the document Tracking Actions with SqlModelMapper; for a complete list of APIs related with SqlModelMapper, refer to SqlModelMapper in SnapObjects .NET API Reference.
SqlExecutor API changes
ILazyQueryable<TModel> SelectLazy<TModel>(string sqlText, params object[] parameters)
This APIs returned a TModel list in the previous version, now it returns the ILazyQueryable<TModel> interface and it no longer requires you to manually open the database connection, but it requires to release the object after used.
#1: use using statement to automatically release the object after iterating ILazyQueryable.
//Initializing the query statement here… var query = … using (var r = _context.SqlExecutor.SelectLazy<D_Sq_Gr_Product>(query, ParamValue.New<int>("param", 500), ParamValue.New<int>("param1", 800))) { //Iterate ILazyQueryablte var item = r.FirstOrDefault(); }
#2: release the object manually.
//Initializing the query statement here… var query = … var r1 = _context.SqlExecutor.SelectLazy<D_Sq_Gr_Product>(query, ParamValue.New<int>("param", 500), ParamValue.New<int>("param1", 800)); foreach(var r in r1) { … } //Release the object r1.Dispose();
Web API changes
If the Web API returns DataStore data type and the client app needs to present the XML data, then the Produces attribute must be added to Action.
[Produces("application/xml")]
[HttpGet]
public IDataStore Load()
{
return _service.Load();
}
.NET DataStore
2.1.0
2.1.0 has the following API changes:
- The IDwMeta interface has a new method: CreateFromSql.
- The Update method of the IDataStoreBase interface has been improved to update data via the dynamically created model (ModelType as DynamicModel).
- The IDataStore interface has a new method: GetReport.
2.0.0
Provide generic .NET DataStores
Generic DataStore (DataStore<TModel>) provides APIs that are used in the .NET style and also the APIs that are commonly used by DataStore.
Code examples for creating a generic DataStore:
var ds = new DataStore<D_Emp>(_context);
ds.Retrieve();
APIs that are used in a greatly different way:
TValue GetItem<TValue>(int row, Func<TModel, TValue> columnSelector, DwBuffer bufferType = DwBuffer.Primary, bool isOriginalValue = false);
This method has the same effect as GetItem of non-generic DataStore. row: Row index. columnSelector: Uses the column selected by delegate bufferType: Buffer area type isOriginalValue: Whether to get the original value
var ds = new DataStore<D_Emp>(_context); ds.Retrieve(); var name = ds.GetItem(0, m => m.Name);
IDataStore<TChildModel> GetChild<TChildModel>(string name);
This method has the same effect as GetChild of non-generic DataStore. name: Uses the property name specified by DwChild attribute
var ds = new DataStore<D_Emp>(_context); ds.Retrieve(); var child = ds.GetChild<D_Dept>("d_dept");
Count property
This property has the same effect as RowCount of non-generic DatatStore.
var ds = new DataStore<D_Emp>(_context); ds.Retrieve() var count= ds.Count;
Sort<TKey>(Func<TModel, TKey> keySelector, bool descending = false);
This method has the same effect as Sort of non-generic DataStore. keySelector: Uses the column selected by delegate descending: Whether to sort the column in a descending order
var ds = new DataStore<D_Emp>(_context); ds.Retrieve(); ds.Sort(m => m.Name, true);
Export and import using DataStore APIs
Refer to DataStoreDataExtensions for a complete list of export and import APIs for DataStores.
Code example for exporting the XML data:
IDataStore ds = new DataStore("d_emp", _contextUt);
ds.Retrieve();
//Use the DataStore ExportXml method to export data in standard XML format
//ExportXml has a few overriding methods
string xml = ds.ExportXml(MappingMethod.Index);
//Use the DataStore ExportPlainXml method to export data in plain XML format
//ExportPlainXml has a few overriding methods
string plainXml = ds.ExportPlainXml()
Code example for importing the XML data:
IDataStore ds = new DataStore("d_emp", _contextUt);
ds.Retrieve();
//Export data from DataStore first
var xml = ds.ExportPlainXml();
// Use the DataStore ImportXml method to import data
//ImportXml has a few overriding methods
string xml = ds.ImportXml(xml);
Export and import using Exporter and Importer (Recommended)
This is the recommended approach, because JSON data is also supported.
Code example for exporting the XML data (GetDataExporter):
IDataStore ds = new DataStore("d_emp", _contextUt);
ds.Retrieve();
//Gets the exporter
var exporter = ds.GetDataExporter(DataFormat.Xml)
//Use the exporter Export method to export data in standard XML format
//Export method has a few overriding methods
string xml = exporter.Export(MappingMethod.Index);
//Use the exporter ExportPlain method to export data in plain XML format
//ExportPlain method has a few overriding methods
string plainXml = ds.ExportPlain()
Code example for importing the XML data (GetDataImporter):
IDataStore ds = new DataStore("d_emp", _contextUt);
ds.Retrieve();
//Export data from DataStore first
var xml = ds.ExportPlainXml();
//Gets the importer
var importer = ds.GetDataImporter(DataFormat.Xml)
//Use the importer Import method to import data
//Import method has a few overriding methods
string xml = importer.Import(xml);
Export using template
Importing data using template is unsupported in 2019 R2.
Code examples for exporting data using template (DwTemplateExporter & TemplateExporter):
- Use the template defined by Model
IDataStore ds = new DataStore("d_emp", _contextUt);
ds.Retrieve()
//Gets the template. If no template is passed in, use the default template.
var dataTemplate = ds.GetTemplate(templateName);
//Sets value for UI element used by the template.
dataTemplate.SetParameter("label1", "d_emp");
//Exports data using template exporter
var data = DwTemplateExporter.Export(ds, dataTemplate);
- Use the external template
IDataStore ds = new DataStore("d_emp", _contextUt);
ds.Retrieve()
//Gets the template content
var template = File.ReadAllText("grid.xml");
//Creates the template object
var dataTemplate = new DataTemplate();
//Loads the template content
dataTemplate.LoadContent(template);
//Exports data using template exporter
var data = DwTemplateExporter.Export(ds, dataTemplate);
Code examples for exporting data of model list using template:
var list = new List<D_Emp>();
//…initializing data
//Gets the template content
var template = File.ReadAllText("grid.xml");
//Creates the template object
var dataTemplate = new DataTemplate();
//Loads the template content
dataTemplate.LoadContent(template);
// Exports data using template exporter
var data = TemplateExporter.Export(list, dataTemplate);
New attributes for model class and property
The SRD file which the DataStore depends on has been removed, and new attributes for model class and property are added to supply the required information (but excluding UI information such as Text control).
For a complete list of model attributes, refer to Attributes for Model Class and Property in .NET DataStore API Reference.
New attributes for model class
DataWindowAttribute (string dataObjectName, DwStyle processing)
Specifies the DataWindow name and presentation style for the model. dataObject: DataWindow name for the model DwStyle: DataWindow presentation style
DwSelectAttribute (string select, [bool IsProcedure])
Specifies the query statement, corresponding to the DataWindow query statement. select: Query statement. IsProcedure: (Optional) Whether the query statement is a stored procedure. Default value is False. Note: if the query statement is a PBSelect, use @(Columns_PlaceHolder) to replace the column definition, for easier maintenance of columns.
DwParameterAttribute (string name, Type dataType)
Specifies the parameters required by the query statement, corresponding to the parameters defined by the DataWindow. Name: Parameter name datatype: Parameter data type
DwSortAttribute (string expression)
Specifies the sort criteria, corresponding to the sort defined by DataWindow expression: sort criteria
DwFilterAttribute (string expression)
Specifies the filter criteria, corresponding to the filter defined by DataWindow expression: filter criteria
UpdateWhereStrategyAttribute (UpdateWhereStrategy strategy)
Specifies the strategy of generating the Where condition for the Update or Delete statement, corresponding to the Where clause defined by DataWindow for update/delete. strategy: An enumerated value that defines the strategy of generating the Where condition.
DwKeyModificationStrategyAttribute (UpdateSqlStrategy sqlStrategy)
Specifies the strategy of generating the SQL statement when the primary key changes, corresponding to the Key Modification defined by DataWindow. sqlStrategy: The strategy of generating the SQL statement when the primary key changes.
DwGroupByAttribute (short level, params string[] groupBy, [string sortBy])
Specifies the grouping criteria, corresponding to the grouping defined by DataWindow level: Level of groups. groupBy: Grouping criteria. sortBy: (Optional) Sorting criteria for groups.
DwUpdateAttribute (DwUpdateAction action, string name)
Specifies the method for the insert, delete or update operation, corresponding to the Stored Procedure Update method defined by DataWindow. action: An enumerated value that defines the update, delete, or insert action. name: The method for the operation.
DwUpdateParameterAttribute (DwUpdateAction action, DwArgumentSource source, string name, string expression, [bool UseOriginal], [ParameterDirection Direction])
Specifies the parameter of the method used by the insert, delete, or update operation, corresponding to the parameter of the Stored Procedure Update method defined by DataWindow. action: The operation corresponding to the parameter source: Data source for the parameter name: Parameter name expression: Data source name UseOriginal: (Optional) Whether to use the original data Direction: Parameter direction
DwDataAttribute (Type dataProviderType)
Specifies the provider for the initialized data, corresponding to the initialized data defined by DataWindow. dataProviderType: The type of the initial data provider. Note: The provider is inherited from the DwDataInitializer class. It contains the data for initializing DataStore. When exporting model from DataWindow, if DataWindow has initialized data, the class of the initial data provider will be automatically created.
DwTemplateAttribute (DataFormat format, string name, string path, [bool IsDefault])
Specifies the template for importing and exporting data, corresponding to the template defined by DataWindow. format: Template format, including json, xml, html. name: Template name path: Template location IsDefault: The default template which will be used at data export. Notes: The DataWindow template must be converted before it can be used by C# DataStore. The DataWindow template will be automatically exported and converted when exporting model from DataWindow.
New attributes for model property
DwColumnAttribute (string column, [string Validation], [string ValidationMsg])
Specifies the column data information, corresponding to the column defined by DataWindow. column: Column name. Validation: (Optional) Validation rules. ValidationMsg: (Optional) Prompts or messages when validation failed. Note: DwColumnAttribute has a few overriding constructors which allow table alias and column alias to be passed in.
DwComputeAttribute (string expression)
Specifies the computed column, corresponding to the computed column defined by DataWindow. expression: Computed column expression.
DwChildAttribute (string dataColumn, string displayColumn, Type modelType, [bool AutoRetrieve])
Specifies the data source, corresponding to the DDDW of DataWindow. dataColumn: Data column. displayColumn: Display data column. modelType: Model type for data source. AutoRetrieve: (Optional) Whether to automatically retrieve data from the data source.
DwReportAttribute (Type modelType)
Specifies the child report, corresponding to the report defined by DataWindow. modelType: Model type for the child report.
Code examples
[DataWindow("d_dddw_login", DwStyle.Grid)]
[Table("Employee")]
#region DwSelectAttribute
[DwSelect("PBSELECT( VERSION(400) TABLE(NAME=\"HumanResources.Employee\" )
@(_COLUMNS_PLACEHOLDER_) ")]
#endregion
[DwSort("businessentityid A ")]
[DwFilter(" businessentityid > 10")]
[UpdateWhereStrategy(UpdateWhereStrategy.KeyAndConcurrencyCheckColumns)]
[DwKeyModificationStrategy(UpdateSqlStrategy.DeleteThenInsert)]
[DwGroupBy(1, "loginid")]
[DwGroupBy(2, "nationalidnumber")]
[DwData(typeof(LoginData))]
public class Login
{
[Key]
[DwColumn("Employee", "BusinessEntityID", Validation = "gettext()<>'NB'", ValidationMsg
= "\"person type not NB\"")]
public int Businessentityid { get; set; } = “NB”;
[ConcurrencyCheck]
[DwColumn("Employee", "NationalIDNumber")]
public string Nationalidnumber { get; set; }
[PropertySave(SaveStrategy.Ignore)]
[DwColumn("Employee", "LoginID")]
public string Loginid { get; set; }
[ConcurrencyCheck]
[SqlDefaultValue("(getdate())")]
[DwColumn("Employee", "ModifiedDate")]
public DateTime Modifieddate { get; set; }
[DwCompute("sum(BusinessEntityID for all)")]
public object Compute_1 { get; set; }
}
public class LoginData : DwDataInitializer<Login>
{
public override IList<Login> GetDefaultData()
{
var datas = new List<Login>();
datas.Add(new Login() { Loginid = "a", Businessentityid = 2 });
datas.Add(new Login() { Loginid = "b", Businessentityid = 5 });
datas.Add(new Login() { Loginid = "c", Businessentityid = 2 });
datas.Add(new Login() { Loginid = "d", Businessentityid = 2 });
datas.Add(new Login() { Loginid = "e", Businessentityid = 2 });
return datas;
}
}
Changed method for loading DataWindow
Now you use the DwModelManager.LoadDwModels() method (instead of using DataObjectFactory.LoadDataWindow) to load DataWindow.
LoadDwModels (Action<IDataWindowOptions> options = null)
This method can load the specified assembly:
DwModelManager.LoadDwModels(m =>
{
m.Assemblies.Add(assembly1);
m.Assemblies.Add(assembly2);
}
);
If this method has no parameter passed in DwModelManager.LoadDwModels();
, it will load all of the classes with DataWindowAttribute from all referenced assemblies.
For more about DwModelManager, refer to DwModelManager in .NET DataStore API Reference.
New attribute for columns used by SQL statement
The DwColumn attribute is added to store the data columns used by SQL statement, so it simplifies modifying SQL statement when adding or deleting data columns.
Just like DataWindow PBSelect, the column name used by SQL statement will be stored in the DwColumn attribute and the actual column name will be replaced by the placeholder @(_COLUMNS_PLACEHOLDER_)
in the SQL statement.
The model DwSelect attribute:
[DwSelect("select @(_COLUMNS_PLACEHOLDER_) from Person.Person")]
The model DwColumn attribute:
[DwColumn(“Person”, “BusinessEntityID”)]
public int BusinessEntityID { get; set; }
Exceptions: if the SQL statement contains union or if the DataWindow is a cross-table report, the column name will not be stored to attribute.
DataTable supports standard data format
To import/export standard-format data for DataTable, you need to add the DWNet.Data namespace first, and then use the GetDataImporter & GetDataExporter to import/export data.
Code example for importing standard-format data:
//Adds the DWNet.Data namespace here
//Initializing JSON data here...
string json = …
var table = new DataTable();
//Gets the DataTable Importer
var importer = table.GetDataImporter(DataFormat.Json);
//Uses the Importer Import method. This method has a few overriding methods.
importer.Import(json);
Code example for exporting standard-format data:
//Adds the DWNet.Data namespace here
var table = new DataTable();
//Initializing table data here...
//Gets the DataTable Exporter
var exporter =table.GetDataExporter(DataFromat.Json);
//Uses the Importer Export method. This method has a few overriding methods.
var json = exporter.Export();
Other new APIs
int RetrieveByKey(params object[] parameters)
Retrieves data by key. Key must be defined by model first.
var ds = new DataStore("d_emp", _context); ds.RetrieveByKey(1);
TModel GetForUpdate<TModel>(int index)
Gets the reference of a model from the buffer. It is different from getting a copy of the model via DataStore index or GetModel method.
var ds = new DataStore("d_emp", _context); ds.Retrieve(); var model = ds.GetForUpdate<D_Emp>(0);
Note: The parameter passed into the DataStore IndexOf and Contains methods must be the model obtained via GetForUpdate.
TModel GetForUpdate<TModel>(Predicate<TModel> predicate)
Gets a model reference from the buffer according to the condition.
var ds = new DataStore("d_emp", _context); ds.Retrieve(); var model = ds.GetForUpdate<D_Emp>(m => m.E_Id == 1);
IEnumerable<TModel> GetForUpdateList<TModel>(Predicate<TModel> predicate)
Gets a model list from the buffer according to the condition.
var ds = new DataStore("d_emp", _context); ds.Retrieve(); var model = ds.GetForUpdateList<D_Emp>(m => m.E_Id > 1);
int RemoveAll<TModel>(Predicate<TModel> predicate)
Moves the data to the delete buffer according to the condition.
var ds = new DataStore("d_emp", _context); ds.Retrieve(); var count = ds.RemoveAll <D_Emp>(m => m.E_Id > 1);
TModel GetModel<TModel>(int row, bool calcCompute);
Gets a data row and calculates the computed column in the row. row: Row index, starting from 0. calcCompute: Whether to calculate the computed column.
var ds = new DataStore("d_emp", _context); ds.Retrieve(); var model = ds.GetModel<D_Emp>(0, true); var count = model.Compute_Count;
TModel GetModelByRowId<TModel>(int rowid, bool calcCompute);
Gets the data row according to the rowid, and calculates the computed column in the row. row: Row index, starting from 0. calcCompute: Whether to calculate the computed column.
var ds = new DataStore("d_emp", _context); ds.Retrieve(); var model = ds.GetModelByRowId <D_Emp>(0, true); var count = model.Compute_Count;
DwMeta property
This property has the same effect as Object. This DwMeta property is recommended.
var ds = new DataStore("d_emp", _context); var meta = ds.DwMeta;
DataContext property
This property has the same effect as SetDataContext. This DataContext property is recommended.
var ds = new DataStore("d_emp"); ds.DataContext = _ context;
IEnumerable<TValue> GetItems<TValue>(short column, DwBuffer bufferType = DwBuffer.Primary)
Gets the data column. It has the same effect as GetValues. column: Column index, starting from 0. bufferType: Buffer area type.
var ds = new DataStore("d_emp", _context); var items = ds.GetItems(0)
IOrderable<TModel> SortBy<TModel>(Func<TModel, object> keySelector);
This method has the same effect as OrderBy. This method is recommended.
IOrderable<TModel> SortByDescending<TModel>(Func<TModel, object> keySelector)
This method has the same effect as OrderByDescending. This method is recommended.
Other changed APIs
bool Remove<TModel>(TModel item)
Moves the data to the delete buffer.
var ds = new DataStore("d_emp", _context); ds.Retrieve(); var model = ds.GetForUpdate(0); var ret = ds.Remove<D_Emp>(model);
Index
PowerBuilder index starts from 1, while C# index starts from 0. PowerBuilder index will minus 1, to be compatible with C# index, in the following scenarios:
When DataWindows are converted C# models
When the column index is used in the expression, for example, left(#1, 1) is changed to left(#0, 0)
When the function parameter is an index, for example:
mid (str, 2, 5) is changed to mid (str, 1, 5)
mid (str1, if (mid (str2, 2, 2) = ‘ac’, 1, 2), 5) is changed to mid (str1, if (mid (str2, 1, 2) = ‘ac’, 1, 2) - 1, 5)
But if function is called during the index calculation process, the result will not minus 1. For example:
Left (str1, if (mid (str2, 2, 2) = ‘ac’, getrow(), 2))
Because getrow function is supposed to return a C# standard result by default, therefore, you will need to manually minus 1.
Left (str1, if (mid (str2, 1, 2) = ‘ac’, getrow(), 2))