Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Support for returning IDictionary<string, object> instead of ExpandoObject. #537

Closed
isaacabraham opened this issue Sep 2, 2020 · 10 comments
Assignees
Labels
deployed Feature or bug is deployed at the current release feature Defined as a big development item (feature) fixed The bug, issue, incident has been fixed. request A request from the community. todo Things to be done in the future

Comments

@isaacabraham
Copy link

F# doesn't have "out of the box" support for dynamic typing (although it's something that you could add support for). Instead, it would be nice to be able to request an IDictionary<String,Object>> from a query e.g.

let data = conn.ExecuteQuery<IDictionary<string, obj>> "SELECT Col1, Col2 FROM Table" // data is type IEnumerable<IDictionary<string, obj>>

let stuff = data |> Seq.map(fun row -> row.["Col1"]) // get a list of all Col1 values

You can work around this with a one liner, but not everyone (and especially developers with no C# experience) will know how to do this:

let data = conn.ExecuteQuery "SELECT Col1, Col2 FROM Table" // data is type IEnumerable<obj>
let dataAsDict = data |> Seq.cast<IDictionary<string, obj>> // dataAsDict is type IEnumerable<IDictionary<string,obj>>
@isaacabraham
Copy link
Author

As background, in F# you can implement the ? operator to do any kind of dynamic lookup so you could do this...

let (?) (x:obj) (key) = (x :?> IDictionary<string, obj>).[key]
let data = conn.ExecuteQuery "SELECT Col1, Col2 FROM Table" // data is type IEnumerable<obj>
let stuff = data |> Seq.map(fun row -> row?Col1) // Note the use of "?" here.

@mikependon
Copy link
Owner

Just to clarify, the resultset of this is of type IEnumerable<IDictionary<string, object>> right? In which, all the mentioned columns types from the SELECT statement will be casted back to System.Object.

@isaacabraham
Copy link
Author

Yes. When you say "all the mentioned columns types" I assume you mean the values in each row (not the column names!)?

And yes, that's what the Expando Object is underneath the hood. It just wraps it in a special interface that C# knows about to give it the dynamic capabilities.

@mikependon
Copy link
Owner

Yes. When you say "all the mentioned columns types" I assume you mean the values in each row (not the column names!)?

Yes, the name = System.String and the value = System.Object.

@mikependon mikependon self-assigned this Sep 2, 2020
@mikependon mikependon added feature Defined as a big development item (feature) request A request from the community. todo Things to be done in the future labels Sep 2, 2020
@isaacabraham
Copy link
Author

Right. I'm not sure what else it could really be? This is what the Expando is behind the scenes. The only other option is potentially to expose the "raw" ADO .NET DB type out so that you can safely ask it what type it is before casting from object to e.g. string etc.

@mikependon
Copy link
Owner

Cool! I will try to see if I can get the data type back as I already have the proper resolver for that. The only reason I ask is because ExpandoObject is only limited to IDictionary<string, object>.

@isaacabraham
Copy link
Author

I think realistically it would probably need to be a <string, obj> collection because each row may have different types in across the columns.

@mikependon
Copy link
Owner

Atleast I can create a thing like this IEnumerable<IDictionary<string, RowValue>>.

public class RowValue
{
	public Type DataType { get; set; }
	public object Value { get; set; } /* This is always object */
}

But I am also afraid to dictate to the user to bind their code to that RowValue object. So, for the sake of simplicity, let us agree with the IDictionary<string, object>, there I will start the implementation.

@mikependon mikependon changed the title Support for returning IDictionary instead of Expando. Enhancement: Support for returning IDictionary<string, object> instead of ExpandoObject. Sep 3, 2020
@mikependon mikependon pinned this issue Sep 3, 2020
mikependon added a commit that referenced this issue Sep 3, 2020
@mikependon mikependon added the fixed The bug, issue, incident has been fixed. label Sep 3, 2020
@mikependon mikependon unpinned this issue Sep 4, 2020
@mikependon mikependon added the deployed Feature or bug is deployed at the current release label Sep 6, 2020
@mikependon
Copy link
Owner

The fix is available at version RepoDb v1.12.0-beta3 or above.

@mikependon
Copy link
Owner

@isaacabraham - we are closing this ticket now. Please do let us know if you still have questions. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deployed Feature or bug is deployed at the current release feature Defined as a big development item (feature) fixed The bug, issue, incident has been fixed. request A request from the community. todo Things to be done in the future
Projects
None yet
Development

No branches or pull requests

2 participants