question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

I have an application where administrators can design the database using a UI and this part of the application is handled without linq2db, meaning, it already works.

If some developer developed a typed entity, it works fine with linq2db but what if there is no typed entity?

Imagine I have a table that linq2db has no idea about. I would like to be able to query that table using the dynamic columns store feature.

class DynamicTable
{
    [PrimaryKey, Identity]
    public long Id { get; set; }

    [DynamicColumnsStore]
    public IDictionary<string, object> ExtendedProperties { get; set; }
}

That requires several things.

  1. Entity method needs a tableName parameter or some unique value that we can use when building schema for multiple DynamicTable instances, because there can be more than one with each having different dynamic columns.
// Current:
Entity<DynamicTable>()

// Hoped:
Entity<DynamicTable>("Table1").Property... // (column1, column2)
Entity<DynamicTable>("Table2").Property... // (otherColumn1, otherColumn2)
  1. DataConnection.GetTable<T> needs another overload there we can pass it the exact DynamicTable instance we want to construct.
// Current:
cnn.GetTable<DynamicTable>();

// Hoped:
cnn.GetTable<DynamicTable>("Table1")
cnn.GetTable<DynamicTable>("Table2")
  1. Use fluent mapper to define dynamic columns in advance. linq2db doesn’t know those but we do. There is one problem here, Sql.Property method is generic. It would be really helpful if there was a non-generic variation of it. So that we don’t have to use reflection.
// Current:
Property(x => Sql.Property<string>(x, "DynColumn"))

// Hoped:
Property(x => Sql.Property(typeof(string), "DynColumn")) // Why do we need "x"?

Finally, the easiest of all of these is being able to implement a custom IDynamicColumnMetadataProvider, something similar to below. That would eliminate all of the requirements above (except GetTable<T>(“name”)). We wouldn’t need to register dynamic columns in advance. You could easily ask us to provide you the list/schema of dynamic columns the first time that table is requested from the connection. I said “except GetTable<T>(name)” because the name parameter is used in the IDynamicColumnMetadataProvider.

class DynamicColumnMetadata
{
    public Type Type { get; set; }
    public Type Name { get; set; }
    public Attribute[] Attributes { get; set; }
}

interface IDynamicColumnMetadataProvider
{
    DynamicColumnMetadata[] GetDynamicColumns(string tableName);
}

class DynamicColumnMetadataProvider : IDynamicColumnMetadataProvider
{
    public DynamicColumnMetadata[] GetDynamicColumns(string tableName)
    {
        if (tableName == "Table1")
        {
            // return dynamic columns for Table1
        }
        else if (tableName == "Table2")
        {
            // return dynamic columns for Table2
        }
    }
}

// On initialize
var ms = new MappingSchema
{
    MetadataReader = new CustomMetadataReader(),
    DynamicColumnsMetadataReader = new CustomDynamicColumnsMetadataReader()
}

cnn.AddMappingSchema(ms);

What is your opinion on this use case? Is there a better approach that I am not aware of?

Thank you in advance!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:31 (27 by maintainers)

github_iconTop GitHub Comments

1reaction
MaceWinducommented, Jan 10, 2019

Some questions/suggestions

  1. Can you use
class Entity1 : DynamicTable {}
class Entity2 : DynamicTable {}

or you cannot assign each table own type?

  1. It is already possible using
db.GetTable<Table>().TableName("table_name")

take into account this issue #1274 and don’t reuse GetTable result

  1. Sql.Property is API for queries, that’s why it is generic and needs x entity parameter. Probably we can add simplified fluent mapper API for dynamic properties to avoid confusion.
0reactions
junsan1commented, Mar 12, 2023
private class TestEntity
{
	public IDictionary<string, object> Extra { get; set; }
}

var entityBuilder = builder.Entity<TestEntity>();

// I can retrieve column names by my own logic
foreach (var colName in new[] { "Col1", "Col2", "Col3" })
{
	entityBuilder.Property(
		colName, // direct set column name

		// getter (simple logic, but can be extended (e.g. I can convert colName into some complex object in case Extra has non primitive key type) so Expression in that case - isn't a good option. Classic delegates do not has limitation like Expression
		(e, colName) => e.Extra[colName],

		// setter (same logic like getter and same possibilities
		(e, colName, rowValue) => e.Extra[colName] = rowValue
	);
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Dynamic Tables
A dynamic table materializes the results of a query that you specify. Rather than creating a separate target table and writing code to...
Read more >
What are Dynamic Tables? - Medium
Dynamic tables are tables that can dynamically change their structure or schema based on certain conditions or events.
Read more >
Dynamic Tables in Excel ( Using Pivot Table and Formulas)
Dynamic Table is the Table where we have to update the range of data repeatedly. The Pivot Table option can create dynamic Tables...
Read more >
What is Snowpipe Streaming and Dynamic Tables?
Dynamic Tables are a new table type in Snowflake that lets data engineers use simple SQL statements to define the end result of...
Read more >
Create Dynamic Tables
A dynamic table is a table that changes its number of rows depending on the render data received via inputs in a Clickwrap...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found