mfenniak / rethinkdb-net

A C# / .NET client driver for RethinkDB.
Other
247 stars 37 forks source link

Experimental prototype of dynamic object support #218

Closed mfenniak closed 9 years ago

mfenniak commented 9 years ago

Experimental work-in-progress!

I'm not quite sure where this work will end up. Here's what I've experimented with so far:

I think fundamentally this is going to run into problems where the returned objects don't come back as the correct .NET types, and there's no avoiding that. For example...

[DataContract]
public class Thing
{
    [DataMember(Name="id")]
    public string Id;
    [DataMember(Name="full_name")]
    public string FullName;
}

var testTable = Query.Db("test").Table<dynamic>("table");
connection.Run(testTable.Insert(new Thing() { Id = "id1", FullName = "Mathieu Fenniak" }));
var readThing = connection.Run(testTable).First();

In this code sample, what type does "readThing" have? All the driver knows is: (a) the library user is asking for a System.Object type (that's what dynamic gets converted to when compiled), and (b) the data is an object with the fields "id" and "full_name".

readThing could be a Dictionary&lt;string,object&gt;, but, then I can't access readThing.Id. It could be a RethinkDbObject (the type I just created in this prototype), and then I can access readThing.id or readThing.full_name, but not readThing.id or readThing.FullName.

Ultimately the best thing to return would be a Thing type, but the driver has no way to identify that as the correct type.

Anyway, aside from that, here are other problems that dynamic support will have:

Upon further investigation, it looks like dynamic operations cannot exist inside an expression tree. This code snippet fails to compile:

var testTable = Query.Db("test").Table<dynamic>("table");
connection.Run(testTable.Insert(new { date = DateTime.UtcNow }));
var retval = connection.Run(testTable.Select(d => d.date.Year));

Because it would be impossible for the compiler to know what type of expression to create for ".date" and ".Year") inside the Select, the C# compiler prevents the usage of dynamic elements inside an expression tree. This is basically a torpedo in the entire idea of using dynamic within rethinkdb-net; if we can't access anything in an expression tree, we'd be severely limited in what we could do.