Generating Geographic Test Data With T-SQL and ChatGPT

When you need lots of test data (100K+) for addresses that represent real places you could leverage ChatGPT and some T-SQL wizardry. 

To do this I asked ChatGPT to give me a list of all the US state capitols and include their longitude and latitude, then turn the data into a TSQL insert statement.

That gives me the longitude and latitude of a point in each state. I created an Address table that will store a list of addresses.

I want to create 100000 rows in the address table.  SQL is really good at manipulating sets of data, so I want to insert rows into the table with a single insert statement, to make the process faster.  To do that I’m going to create a table variable and populate it with a list of integers.  Lots of integers. 

Once the table is created, I can insert a single row to seed the table, with the number 1.  A while loop can be used to double the number of inserts over each iteration by selecting all the rows in the table and multiplying the integer by 2.

Now that we have a table of integers from 1 to 2,000,000, I can use the table to create new data.

I’ll select all the rows from the @Nums table where the number is less than or equal to the number of addresses I want to create.  In this case 100,000.  I also want to join with the table of state capitals, so I can use the city, state, longitude and latitude fields to populate the data.  I can use the modulus operator to match with one of the 50 rows in the state capitols table.

To convert the longitude and latitude to a geography column type, I can use the STGeomFromText function.  If you needed locations with more variance, you could add a small random value to the longitude and latitude of each row as it’s inserted into the address table. The script took about 15 seconds to populate the table, but most of the time was in calculating the geography value, so using the table of numbers to generate data is very fast.

Supercharged Dapper Repositories

Part #1: Separate Filters From Queries

Dapper has been a really popular data access library for over a decade, but when it comes to use it with domain entities, there are a few things that can create friction. In this series, I want to show you how to supercharge your Dapper repositories to be faster and more maintainable.

Sample Code: https://github.com/JZuerlein/DapperPopulateAggregate

Chicago Code Camp 2018

I’m very excited to present in this year’s Chicago Code Camp!

This year’s topic is …

Authorization in ASP.NET Core: Tips for securing modern applications!

Microsoft’s transition to a claims based identity model, and policy based authorization opens the door to new techniques to manage modern applications. I’ll briefly explain the basics of Authorization in ASP.NET Core, then take a deeper dive into custom policies, authentication schemes, combining authorization requirements, resource-based, and view-based authorization. We’ll look at how these techniques can decouple authorization logic from business code and facilitate unit testing. Finally, I’ll talk about the benefits of using an authorization server when trying to administer the services feeding your applications.

If you attended my session and want to get a copy of the presentation or demo code, you’ve come to the right place.

Power Point
Source Code

DevExpress: Updating a dxGrid widget.

DevExpress has a line of web controls that I’ve been playing with.
https://js.devexpress.com/

On the whole, I think they are good. I have found the documentation to be plentiful, but the specifics can be scattered in different places. Which is why I’m sharing my experience with their data grid control. It’s more formally called a dxDataGrid. My goal was to simply have an input tag that could hold a foreign key ID. When that value changed, I wanted the data grid to be updated with JSON data from a WebAPI. Pretty common scenario, but I didn’t see a copy & paste example in the documentation that didn’t use Angular. So here is an example to save you some time.

I’m limiting the code to only the relevant parts. It basically displays a list of applications. When you click on one, the data grid gets populated with a list of roles for the application.

Index.cshtml

<div id="applicationList"></div>
<input id=”applicationExternalID” />
<div id=”applicationRolesGrid”></div>

In terms of the markup, this is pretty minimal. DevExpress offers some tag helpers that you can use to create the controls, but they stick a bunch of java script in the middle of the HTML, and I rather keep the java script in separate files. All the configuration can be done in JS.

Index.js

(function ($) {
    
    var applicationList = $("#applicationList").dxList({
        dataSource: DevExpress.data.AspNet.createStore({
            key: "ApplicationID",
            loadUrl: "https://localhost:44356/application/GetApplicationsByTenant",
            onBeforeSend: function (method, ajaxOptions) {
                ajaxOptions.xhrFields = { withCredentials: true };
            }
        }),
        height: 400,
        itemTemplate: function (data) {
            return $("<div>").text(data.DisplayName);
        },
        onItemClick: function (e) {
            var externalID = e.itemData.ExternalID;
            $("#applicatonExternalID").val(externalID);
            $("#DisplayName").text(e.itemData.DisplayName);

            roleSource = DevExpress.data.AspNet.createStore({
                key: "ApplicationRoleID",
                loadUrl: "https://localhost:44356/application/GetApplicationRolesByApplication",
                loadParams: { externalID: externalID },
                onBeforeSend: function (method, ajaxOptions) {
                    ajaxOptions.xhrFields = { withCredentials: true };
                }
            })
            applicationRolesGrid.option('dataSource', roleSource);
            applicationRolesGrid.refresh();
        }
    }).dxList("instance");

    var rolesSource = DevExpress.data.AspNet.createStore({
        key: "ApplicationRoleID",
        loadUrl: "https://localhost:44356/application/GetApplicationRolesByApplication",
        onBeforeSend: function (method, ajaxOptions) {
            ajaxOptions.xhrFields = { withCredentials: true };
        }
    })

    var applicationRolesGrid = $("#applicationRolesGrid").dxDataGrid({
    
        columns: [{
            dataField: "ApplicationRoleID",
            width: 80
        }, {
            dataField: "DisplayName"
        }],

        paging: {
            pageSize: 10
        }
    }).dxDataGrid("instance");

}(jQuery))

So the first thing to take note of is the data stores that are used. DevExpress has created a project on GitHub that allows their client side widgets (controls) to consume data from a ASP.NET web api.
https://github.com/DevExpress/DevExtreme.AspNet.Data
In the case of loading data for the list of applications, I was able to provide the data store with a URL to get the data. You can pass it credentials, and specify a key for each unique record. This is a pretty easy use case. To tell the dxList to use the data store, just set the list’s dataSource parameter to an instance of the data store. The rest is pretty much magic.

I actually create a second data store to get the list of roles for the selected application. This one will require the use of a parameter called loadParams. The WebAPI has a function that takes in a string called externalID, so the loadParams is provided with an object that contain the property externalID.

public async Task<IActionResult> GetApplicationRolesByApplication(string externalID)

This parameter should change every time a different item is clicked in the dxList. So I’ve added a handler to the dxList.onItemClick event. When that happens, I need to update the loadParams object with the new externalID. Here is the sticky party. I expected that I could call the data grid’s refresh method, and it would make the call to the web api and display the new data. But that’s not the case. I actually had to reassign the dxGrid’s dataSource property. That can be done by using the option function to reassign the dataSource property.

applicationRolesGrid.option('dataSource', roleSource);

This is really pretty simple to use, you have to find all the bits that need to be touched. If you know of better ways to do this, feel free to post in the comments.