anon
anon

Reputation:

Creating a table using Datastax Cassandra .NET Client

I'm trying out the DataStax Cassandra .NET driver and I'm attempting to implement something more complex than a bucket of strings (see https://gist.github.com/peschkaj/5794713).

When I attempt to create the table using

var table = session.GetTable<SalesOrder>();
table.CreateIfNotExists();

I get the following exception:

System.InvalidOperationException: Operation is not valid due to the current state of the object
  at Cassandra.Data.Linq.CqlQueryTools.GetCqlTypeFromType (System.Type tpy) [0x00000] in <filename unknown>:0
  at Cassandra.Data.Linq.CqlQueryTools.GetCreateCQL (ITable table) [0x00000] in <filename unknown>:0
  at Cassandra.Data.Linq.Table`1[CassandraTest.SalesOrder].Create (ConsistencyLevel consictencyLevel) [0x00000] in <filename unknown>:0
  at Cassandra.Data.Linq.Table`1[CassandraTest.SalesOrder].CreateIfNotExists (ConsistencyLevel consictencyLevel) [0x00000] in <filename unknown>:0
  at CassandraTest.MainClass.Main (System.String[] args) [0x00056] in /Users/jeremiah/Projects/CassandraTest/CassandraTest/Program.cs:71

The operation fails, in part, because of the DateTime and in part because of the custom types. What is the appropriate syntax/pattern/etc for saving complex objects back to Cassandra using the C# driver?

Upvotes: 3

Views: 3786

Answers (1)

Derek Bromenshenkel
Derek Bromenshenkel

Reputation: 275

Looking at the code, it appears the driver only has a mapping for timestamp -> DateTimeOffset type (see code). If you change your DateTime objects to DateTimeOffset, it fixes that problem. I'm not thrilled with the fact that they have ignored the mapping for DateTime type, though.

The driver does not understand your nested complex types Address or LineItem, nor is there a built-in way (ORM) for it to do that. I see two options:

  1. Serialze your object into JSON and then the column "value" can just be your string of JSON. Upon fetch, you re-hydrate your .NET object from the JSON. This is what we do in our CQL 2.0 implementation, and is the only option for CQL 2.0. It works well. We do it all over the place and the overhead we've measured is negligible compared to the other things we do in our app.
  2. Because your Address and LineItem classes contain only primitive types, you could probably represent them as a Dictionary<K,V> which translates into a CQL 3.0 map data type. Again, it would require manual intervention if you wanted a strongly typed object.
    • The problem with this for ListItem is that a CQL 3.0 list cannot contain another collection - in this case a map. You're back to JSON for that, and of course the advantage is you can get as complex as you want as long as it is serializable.

I forked your gist and made some crude tweaks to give you an idea of how to get this basic example working. https://gist.github.com/dlbromen/5811969

Upvotes: 1

Related Questions