Questions? Feedback?powered byOlark live chat software

PowerBuilder 2018 Preview – C# Development

Overview

PowerBuilder 2018 allows developers to code in C# using the native PowerBuilder IDE.  A new set of targets are provided for C#, which power the easy & rapid creation, in a test-driven manner, of server-side business objects (.NET assemblies and RESTful Web APIs).  You get the productivity that is a hallmark of PowerBuilder along with the key benefits of the .NET platform & cloud architecture.

This is a total revamp of PowerBuilder’s existing .NET targets. ​ As such, development is done using the C# language and powered by open standards, such as the open-source .NET Core and the OAuth standard.  The server runtime libraries are 100% stateless and thread-safe design.  You should experience greater security, performance, and portability than before.

PowerBuilder 2018 expands your development arsenal with C# in a very short time.  It’s so easy to learn because you use the familiar PowerBuilder IDE to write C# that is centered around the beloved DataWindow.  With practically all the same non-visual properties and functions as before, you may not even need to bother with any documentation!

Compared to traditional C# development in Visual Studio, PowerBuilder 2018 offers the following key benefits:

Low Learning
Curve

As little as 2 weeks.

Less Coding & Testing

Even less than PowerScript.

Easy Migration


Migration tools provided.

Productivity

Stop wasting time writing tons of code!

public IDataStore GetOrderCustomerInfo(DateTime startDate, DateTime endDate, decimal amount)
{
    IDataStore dataStore = new DataStore("d_order_customer", _context);
    dataStore.Retrieve(startDate, endDate, amount);
    return dataStore;
}
public IEnumerable<d_order_customer> GetOrderCustomerInfo(DateTime startDate, DateTime endDate, decimal amount)
{
    var query = from c in _context.Set<efcore_customer>()
                from p in _context.Set<efcore_person>()
                from s in _context.Set<efcore_salesorderheader>()
                where c.PersonId == p.Businessentityid &&
                      s.CustomerId == c.CustomerId &&
                      s.OrderDate >= startDate &&
                      s.OrderDate <= endDate
                group s.SubTotal by new
                {
                    p.Title,
                    p.Firstname,
                    p.Middlename,
                    p.Lastname,
                    c.ModifiedDate,
                    c.CustomerId
                } 
                into g
                let avg = g.Average()
                where avg > amount
                orderby avg
                select new D_Order_Customer
                {
                    Person_Title = g.Key.Title,
                    Person_Firstname = g.Key.Firstname,
                    Person_Middlename = g.Key.Middlename,
                    Person_Lastname = g.Key.Lastname,
                    Customer_Modifieddate = g.Key.ModifiedDate,
                    Customer_Customerid = g.Key.CustomerId,
                    Sumamt = g.Sum(),
                    Avgamt = avg
                };
 
    return query.ToList();
}
 
 
 
//code of model 
public class D_Order_Customer
{
    [SqlColumn("Title")]
    public String Person_Title { get; set; }
 
    [SqlColumn("FirstName")]
    public String Person_Firstname { get; set; }
 
    [SqlColumn("MiddleName")]
    public String Person_Middlename { get; set; }
 
    [SqlColumn("LastName")]
    public String Person_Lastname { get; set; }
 
    [SqlColumn("ModifiedDate")]
    public DateTime Customer_Modifieddate { get; set; }
    [Key]
    [Identity]
    [SqlColumn("CustomerID")]
    public Int32 Customer_Customerid { get; set; }
 
    [SqlColumn("sumamt")]
    public Decimal Sumamt { get; set; }
 
    [SqlColumn("avgamt")]
    public Decimal Avgamt { get; set; }
}
public function datastore of_retrieve (date ad_start, date ad_end, decimal adec_amt); 
Datastore lds
lds = Create Datastore
lds.dataobject = "d_order_customer"
lds.SetTransObject(SQLCA) 
lds.Retrieve(ad_start, ad_end, adec_amt) 
Return lds 
end function

You really can’t beat the power of the C# DataStore object and PowerBuilder’s visual development.  If you prefer to do non-visual C# development, PowerBuilder 2018 also offers a C# ModelStore object that is still less C# coding than the Entity Framework.

Stop wasting time writing & testing SQL!

 Automatic SQL Generation

PowerBuilder 2018 automatically generates SQL, no matter you use embedded SQLdynamic SQLDataStore, or the new ModelStore.  You no longer need to spend time ensuring SQL is cross-database compatible.

 Automatic SQL Testing

PowerBuilder 2018 automatically validates the syntax of all generated SQL as well as the actual data operation against your database.  You no longer need to spend time running your app to discover basic SQL issues.  

 Data Model Architecture

PowerBuilder 2018 supports a data model architecture where data access logic is partitioned in data models.  You no longer need to spend time writing redundant SQL or code to bind your result sets to data models.

Stop wasting time on performance tuning!

See if you can tell which C# code performs well?

public IEnumerable<d_order_customer> GetOrderCustomerInfo(DateTime startDate, DateTime endDate, decimal amount)
{
    var query = from c in _context.Set<efcore_customer>()
                from p in _context.Set<efcore_person>()
                from s in _context.Set<efcore_salesorderheader>()
                where c.PersonId == p.Businessentityid &&
                      s.CustomerId == c.CustomerId &&
                      s.OrderDate >= startDate &&
                      s.OrderDate <= endDate
                group s.SubTotal by new
                {
                    p.Title,
                    p.Firstname,
                    p.Middlename,
                    p.Lastname,
                    c.ModifiedDate,
                    c.CustomerId
                } 
				into g
                let avg = g.Average()
                where avg > amount
                orderby avg
                select new D_Order_Customer
                {
                    Person_Title = g.Key.Title,
                    Person_Firstname = g.Key.Firstname,
                    Person_Middlename = g.Key.Middlename,
                    Person_Lastname = g.Key.Lastname,
                    Customer_Modifieddate = g.Key.ModifiedDate,
                    Customer_Customerid = g.Key.CustomerId,
                    Sumamt = g.Sum(),
                    Avgamt = avg
                };

    return query.ToList();
}



//code of model 
public class D_Order_Customer
{
    [SqlColumn("Title")]
    public String Person_Title { get; set; }

    [SqlColumn("FirstName")]
    public String Person_Firstname { get; set; }

    [SqlColumn("MiddleName")]
    public String Person_Middlename { get; set; }

    [SqlColumn("LastName")]
    public String Person_Lastname { get; set; }

    [SqlColumn("ModifiedDate")]
    public DateTime Customer_Modifieddate { get; set; }
    [Key]
    [Identity]
    [SqlColumn("CustomerID")]
    public Int32 Customer_Customerid { get; set; }

    [SqlColumn("sumamt")]
    public Decimal Sumamt { get; set; }

    [SqlColumn("avgamt")]
    public Decimal Avgamt { get; set; }
}
public IEnumerable<d_order_customer> GetOrderCustomerInfo(DateTime startDate, DateTime endDate, decimal amount)
{
    var query = from c in _context.Set<efcore_customer>()
                join p in _context.Set<efcore_person>() 
                    on c.CustomerId equals p.Businessentityid
                join s in _context.Set<efcore_salesorderheader>()
                    on c.CustomerId equals s.CustomerId
                where s.OrderDate >= startDate &&
                      s.OrderDate <= endDate
                group s.SubTotal by new
                {
                    p.Title,
                    p.Firstname,
                    p.Middlename,
                    p.Lastname,
                    c.ModifiedDate,
                    c.CustomerId
                } 
				into g
                let avg = g.Average()
                where avg > amount
                orderby avg
                select new D_Order_Customer
                {
                    Person_Title = g.Key.Title,
                    Person_Firstname = g.Key.Firstname,
                    Person_Middlename = g.Key.Middlename,
                    Person_Lastname = g.Key.Lastname,
                    Customer_Modifieddate = g.Key.ModifiedDate,
                    Customer_Customerid = g.Key.CustomerId,
                    Sumamt = g.Sum(),
                    Avgamt = avg
                };

    return query.ToList();
}



//code of model 
public class D_Order_Customer
{
    [SqlColumn("Title")]
    public String Person_Title { get; set; }

    [SqlColumn("FirstName")]
    public String Person_Firstname { get; set; }

    [SqlColumn("MiddleName")]
    public String Person_Middlename { get; set; }

    [SqlColumn("LastName")]
    public String Person_Lastname { get; set; }

    [SqlColumn("ModifiedDate")]
    public DateTime Customer_Modifieddate { get; set; }
    [Key]
    [Identity]
    [SqlColumn("CustomerID")]
    public Int32 Customer_Customerid { get; set; }

    [SqlColumn("sumamt")]
    public Decimal Sumamt { get; set; }

    [SqlColumn("avgamt")]
    public Decimal Avgamt { get; set; }
}
public IEnumerable<d_order_customer> GetOrderCustomerInfo(DateTime startDate, DateTime endDate, decimal amount)
{
    var query = _context.Set<efcore_customer>()
                .Join(_context.Set<efcore_person>(),
                        c => c.PersonId,
                        p => p.Businessentityid,
                        (c, p) => new
                        {
                            p.Title,
                            p.Firstname,
                            p.Middlename,
                            p.Lastname,
                            c.ModifiedDate,
                            c.CustomerId,
                        })
                .Join(_context.Set<efcore_salesorderheader>(),
                        cp => cp.CustomerId,
                        s => s.CustomerId,
                        (cp, s) => new
                        {
                            cp,
                            s
                        })
                .Where(m => m.s.OrderDate >= startDate && 
							m.s.OrderDate <= endDate)
                .GroupBy(m => m.cp, n => n.s.SubTotal)
                .Where(m => m.Sum() > amount)
                .Select(g => new D_Order_Customer
                {
                    Person_Title = g.Key.Title,
                    Person_Firstname = g.Key.Firstname,
                    Person_Middlename = g.Key.Middlename,
                    Person_Lastname = g.Key.Lastname,
                    Customer_Modifieddate = g.Key.ModifiedDate,
                    Customer_Customerid = g.Key.CustomerId,
                    Sumamt = g.Sum(),
                    Avgamt = g.Average()
                })
                .OrderBy(m => m.Avgamt);

    return query.ToList();
}



//code of model 
public class D_Order_Customer
{
    [SqlColumn("Title")]
    public String Person_Title { get; set; }

    [SqlColumn("FirstName")]
    public String Person_Firstname { get; set; }

    [SqlColumn("MiddleName")]
    public String Person_Middlename { get; set; }

    [SqlColumn("LastName")]
    public String Person_Lastname { get; set; }

    [SqlColumn("ModifiedDate")]
    public DateTime Customer_Modifieddate { get; set; }
    [Key]
    [Identity]
    [SqlColumn("CustomerID")]
    public Int32 Customer_Customerid { get; set; }

    [SqlColumn("sumamt")]
    public Decimal Sumamt { get; set; }

    [SqlColumn("avgamt")]
    public Decimal Avgamt { get; set; }
}
public IDataStore GetOrderCustomerInfo(DateTime startDate, DateTime endDate, decimal amount)
{
    IDataStore dataStore = new DataStore("d_order_customer", _context);
    dataStore.Retrieve(startDate, endDate, amount);
    return dataStore;
}

The answer is C# DataStore, and you can see how simple the code is.  Simple code makes it difficult to write poor-performing code!  Of course it is possible to optimize C# code for the Entity Framework if you are very experienced and spend the time. But why do that?

Try out the performance benchmarks to see how to optimize C# code for the Entity Framework so it performs as good as the C# DataStore!

Stop manually creating data models/objects!

All existing PowerScript-based DataWindow (including DataStore) data objects migrate automatically to C# DataStores and data models.  Imagine the time savings of not having to re-create your DataWindows and not having to create all the data models (required by the Entity Framework).

If you prefer to use the new C# ModelStore object, PowerBuilder 2018 takes care of creating all the data models for you (even query models)… something the Entity Framework doesn’t do for you out-of-the-box.

Features

You have at your disposable all the features any other C# developer could possibly use for creating server-side business objects (because it’s running on .NET).  But you also get the powerful ORM features of PowerBuilder, plus some other goodies (that we’ll reveal when PowerBuilder 2018 is generally available).

Compared to the leading ORMs for C#, developing with PowerBuilder 2018 offers some valuable features and 100% eliminates the need to hand-code SQL.

PowerBuilder 2018 C# Entity Framework 6.2 Dapper 1.5
ORM Functionality
Tracking Changes
Lambda Expressions
Dynamic SQL
SQL Generation
SQL Syntax Validation
SQL Operation Validation
Data Model Generation Entities Only
Data Model Validation

Portability

PowerBuilder 2018 has been carefully designed with portability in mind such that you can benefit from…

Other Tools

Develop with any C# IDE, but of course PowerBuilder should save you more time.

Other Languages

Integrate natively with any other .NET languages – F#, Visual Basic, etc.

Other Systems

Expose and consume Web APIs using popular open standards – REST, JSON, OAuth, etc.

Other Databases

Readily port your app across various databases (SQL is 100% automatically generated for you).

Other OS

Deploy to Windows or Linux, any .NET server, and leading cloud providers.

How does PowerBuilder 2018 achieve such portability but also save so much time?

Pure C# Coding

PowerBuilder 2018 facilitates coding of server objects 100% in C#.  That means absolutely ZERO hand-coding of SQL (SQL is automatically generated for you).

Managed Code

PowerBuilder 2018's server runtime components (e.g. DataStore, ModelStore, SQLExecutor) are 100% managed .NET code.

.NET Core

PowerBuilder 2018 is powered by the .NET Core, which is Microsoft’s open-source, cross-OS, high-performance, server-side .NET framework. Learn more...

Demos

C# DataStore

The power of the native DataStore in a pure C# and n-tier architecture, with essentially the same set of APIs.

C# ModelStore

An alternative to the C# DataStore.  Code C# directly against data models and get even faster performance.

SQLExecutor

Stop hand-coding SQL! The SQLExecutor generates SQL for you that binds to either POCO or dynamic models.