9

The only references I can find is someone suggesting to use Entity Framework to do this, but I don't have or use Entity Framework. The only other thing on this subject is going from SQL table to C# class, which is the opposite of what I want.

This doesn't have to be TSQL/MSSQL (2014) Compatible but that's my DBMS.

The C# class is just a POCO. I think I heard you could take the class and somehow convert it a DataTable and then using SqlBulkCopy have it create a table from the DataTable.

This is what I am currently using it uses a SELECT INTO and casting a null to a sqlType to make nullable columns. As you can see it's quite raw but gets the job done mostly - I am looking for less error prone methods.

        var columnNames = GetColumnsToBeUpdated<T>().ToList();
        var columnTypes = GetColumnsTypesToBeUpdated<T>().ToList();


        var selects = columnNames.Select((t, i) => $"CAST(NULL as {columnTypes[i]}) AS [{t}]");

        var createsql = $@"
            SELECT {string.Join(", ", selects)}
            INTO SDE.[{tableName}]";

        using (var connection = new SqlConnection(_sdeConnectionString))
        {
            EsriServer.ExecuteNonQuery(connection, $"IF OBJECT_ID(N'SDE.[{tableName}]', N'U') IS NOT NULL " +
                                                   $"DROP TABLE SDE.[{tableName}]", null);
            EsriServer.ExecuteNonQuery(connection, createsql, null);
            EsriServer.ExecuteNonQuery(connection, $"TRUNCATE TABLE SDE.[{tableName}]", null);
        }

    private static string GetSqlDataType(Type type)
    {
        var name = type.Name;
        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            name = type.GetGenericArguments()[0].Name;
        }

        switch (name)
        {
            case "Guid":
                return "uniqueidentifier";
            case "Boolean":
                return "bit";
            case "Byte":
                return "tinyint";
            case "Int16":
                return "smallint";
            case "Int32":
                return "int";
            case "Int64":
                return "bigint";
            case "Decimal":
                return "decimal(38,25)";
            case "Single":
                return "real";
            case "Double":
                return "float";
            case "DateTime":
                return "datetime";
            case "String":
            case "Char[]":
                return "nvarchar(max)";
            case "Char":
                return "nvarchar(1)";
            case "Byte[]":
                return "varbinary";
            case "Object":
                return "sql_variant";
            default:
                throw new ArgumentOutOfRangeException();
        }
    }

    private static IEnumerable<string> GetColumnsToBeUpdated<T>() where T : class, new()
    {
        var typeT = new T();
        var ps = typeT.GetType().GetProperties();
        var propertyNames = ps.Select(p => p.Name);

        return propertyNames.Except(GetColumnsToBeIgnored<T>());
    }

    private static IEnumerable<string> GetColumnsTypesToBeUpdated<T>() where T : class, new()
    {
        var typeT = new T();
        var ps = typeT.GetType().GetProperties();
        return ps.Select(p => p.PropertyType).Select(GetSqlDataType).ToList();
    }

If this can't be done accurately or requires major code then I am pretty fine with an application or online server that lets me paste in a simple C# class and get back a create table statement.

4
  • Figuring out how to map a simple type to a brand new DB table is a fairly trivial task. How you're going to handle 1) tables that already have data 2) synchronizing your class and tables 3) deploy your structures to various environments 4) deal with POCO's that aren't easily mapped 5) handle various database constraints are the reason why this isn't a reasonable question. Perhaps you should consider a NoSQL route Commented Apr 21, 2017 at 21:40
  • 1) that could easily be an input to the creator 2) not needed 3) not needed 4) not a requirement, simple pocos only 5) C# tries its best, if SQL cant do it then it cant do it. I am not looking for an enterprise solution, but something that is straight forward and easy to read while still giving functionality. Commented Apr 21, 2017 at 22:36
  • I think you missed my point. Solving the trivial case isn't worthwhile Commented Apr 21, 2017 at 22:43
  • Possible duplicate: stackoverflow.com/.../how-can-i-generate-database-tables-from-c-sharp-classes Commented Aug 2, 2019 at 4:10

1 Answer 1

13

You can convert the C# class to Json and then convert the Json to Sql.

Convert C# class to Json:

Convert Json to SQL online:

Sign up to request clarification or add additional context in comments.

3 Comments

cshar2json.io and sqlify.io have certificate problems. jsonutils.com gives a 404
Working websites for C# to JSON : class2json.net, for JSON to Sql : convertjson.com/json-to-sql.htm
The best one for C# entity object to SQL Server Table syntax: zzzcode.ai/dapper/entity-to-table-converter

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.