Getting Started with Datatsax .Net Driver

353 views
261 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
353
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Getting Started with Datatsax .Net Driver

  1. 1. Getting Started with DataStax .NET Driver Luke Tillman Language Evangelist @LukeTillman
  2. 2. Life as the .NET Language Evangelist
  3. 3. Where do I get the driver? • NuGet • GitHub • https://github.com/datastax/csharp-driver
  4. 4. Bootstrapping the Driver
  5. 5. Cluster • Singleton - one per application • Use the Builder Cluster cluster = Cluster.Builder() .AddContactPoint("127.0.0.1") .Build();
  6. 6. Cluster • Fluent Interface with Lots of Options var authProvider = new PlainTextAuthProvider("username", "password"); var queryOptions = new QueryOptions() .SetConsistencyLevel(ConsistencyLevel.LocalQuorum) .SetPageSize(1000); Cluster cluster = Cluster.Builder().AddContactPoint("127.0.0.1") .WithSSL() .WithQueryOptions(queryOptions) .WithAuthProvider(authProvider) .Build();
  7. 7. Session • Singleton per keyspace • Inspired by the (N)Hibernate session object • Get it from your Cluster object ISession session = cluster.Connect("killrvideo");
  8. 8. Sample IoC Container Registration // Use the Cluster builder to create a cluster Cluster cluster = Cluster.Builder().AddContactPoint("127.0.0.1").Build(); // Use the cluster to connect a session to the appropriate keyspace ISession session = cluster.Connect("killrvideo"); // Register both Cluster and ISession instances with Windsor (as // Singletons since it will reuse the instance) container.Register( Component.For<Cluster>().Instance(cluster), Component.For<ISession>().Instance(session) );
  9. 9. Creating Statements
  10. 10. Types of Statements • SimpleStatement • PreparedStatement / BoundStatement • BatchStatement
  11. 11. SimpleStatement • It’s… simple? • Can use bind parameters • Useful for one-off statements or dynamic CQL where you can’t prepare it var statement = new SimpleStatement("SELECT * FROM users WHERE userid = ?"); statement = statement.Bind(145);
  12. 12. PreparedStatement / BoundStatement • Pay the cost of Prepare once (server roundtrip) • Save the PreparedStatement instance and reuse PreparedStatement prepared = session.Prepare( "SELECT * FROM user_credentials WHERE email = ?");
  13. 13. PreparedStatement / BoundStatement • Bind variable values to get BoundStatement for execution • Execution only has to send variable values • You will use these all the time BoundStatement bound = prepared.Bind("luke.tillman@datastax.com");
  14. 14. BatchStatement • Add Simple/Bound statements to a batch BoundStatement bound = prepared.Bind(video.VideoId, video.Name); var simple = new SimpleStatement( "UPDATE videos SET name = ? WHERE videoid = ?" ).Bind(video.Name, video.VideoId); // Use an atomic batch to send over all the mutations var batchStatement = new BatchStatement(); batchStatement.Add(bound); batchStatement.Add(simple);
  15. 15. BatchStatement • Batches are Logged, atomic (by default) and this is the most common use case • Set the batch type to use a different type of batch • Counters have their own batch type (can’t mix) var batch = new BatchStatement().SetBatchType(BatchType.Unlogged);
  16. 16. Statements – You’ve Got Options • Simple and Bound statements have options that can be set at the Statement level • Consistency Level • Retry Policy • Paging Size (for automatic paging, we’ll come back to this) • Tracing • If not set at the statement level, defaults set when configuring/building the Cluster are used
  17. 17. Statements – You’ve Got Options • Example of binding a PreparedStatement and setting available options: IStatement bound = prepared.Bind("luke.tillman@datastax.com") .SetPageSize(100) .SetConsistencyLevel(ConsistencyLevel.LocalOne) .SetRetryPolicy(new DefaultRetryPolicy()) .EnableTracing();
  18. 18. Executing Statements and Getting the Results
  19. 19. Executing Statements • Use your Session object to execute statements • You can execute statements synchronously or asynchronously • Synchronous • Asynchronous • Execute methods return a RowSet RowSet rows = await _session.ExecuteAsync(boundStatement); RowSet rows = _session.Execute(boundStatement);
  20. 20. RowSet • RowSet implements IEnumerable<Row> • Use GetValue<T> method on a Row to get a column’s value • By column name • By ordinal (position)
  21. 21. RowSet • Because RowSet implements IEnumerable<Row>: • Iterate with foreach RowSet rows = await _session.ExecuteAsync(boundStatement); foreach (Row row in rows) { returnList.Add(new VideoPreview { VideoId = row.GetValue<Guid>("videoid"), AddedDate = row.GetValue<DateTimeOffset>("added_date"), Name = row.GetValue<string>("name") }); }
  22. 22. RowSet • Because RowSet implements IEnumerable<Row>: • Project Rows with LINQ to Objects Select() RowSet rows = await _session.ExecuteAsync(boundStatement); var returnList = rows.Select(row => new VideoPreview { VideoId = row.GetValue<Guid>(0), AddedDate = row.GetValue<DateTimeOffset>(1), Name = row.GetValue<string>(2) }).ToList();
  23. 23. RowSet • Because RowSet implements IEnumerable<Row>: • Get a single row with LINQ to Objects Single() or SingleOrDefault() RowSet rows = await _session.ExecuteAsync(boundStatement); Row row = rows.SingleOrDefault();
  24. 24. CQL 3 Data Types to .NET Types Full listing available in driver docs CQL 3 Data Type .NET Type bigint, counter long boolean bool decimal, float float double double int int uuid, timeuuid System.Guid text, varchar string (Encoding.UTF8) timestamp System.DateTimeOffset varint System.Numerics.BigIntege r
  25. 25. Driver 2.0 Features
  26. 26. Lightweight Transactions (LWT) • Use when you don’t want writes to step on each other • AKA Linearizable Consistency • Serial Isolation Level • Be sure to read the fine print: has a latency cost associated with using it, so use only where needed • The canonical example: unique user accounts
  27. 27. Lightweight Transactions (LWT) • Returns a column called [applied] indicating success/failure • Different from the relational world where you might expect an Exception (i.e. var statement = new SimpleStatement("INSERT INTO user_credentials (email, password) VALUES (?, ?) IF NOT EXISTS"); statement = statement.Bind("user1@killrvideo.com", "Password1!"); RowSet rows = await _session.ExecuteAsync(statement); var userInserted = rows.Single().GetValue<bool>("[applied]");
  28. 28. Automatic Paging • The Problem: Loading big result sets into memory is a recipe for disaster (OutOfMemoryExceptions, etc.) • Better to load and process a large result set in pages (chunks) • Doing this manually with Cassandra prior to 2.0 was a pain
  29. 29. Automatic Paging • Set a page size on a statement (or will use default from Cluster) • Iterate over the resulting RowSet • As you iterate, new pages are fetched transparently when the Rows in the current page are exhausted • Will allow you to iterate until all pages are exhausted boundStatement = boundStatement.SetPageSize(100); RowSet rows = await _session.ExecuteAsync(boundStatement); foreach (Row row in rows) { }
  30. 30. Typical Pager UI in a Web Application • Show page of records in UI and allow user to navigate
  31. 31. Typical Pager UI in a Web Application • Automatic Paging – this is not the feature you are looking for
  32. 32. Where To Go From Here
  33. 33. LINQ to CQL • Comes in the NuGet package as Cassandra.Data.Linq • Has support for all CRUD operations • Start by decorating the objects you’ll be querying with Table, Column, and PartitionKey attributes
  34. 34. LINQ to CQL [Table("user_credentials")] public class UserCredentials { [Column("email")] [PartitionKey] public string EmailAddress { get; set; } [Column("password")] public string Password { get; set; } [Column("userid")] public Guid UserId { get; set; } }
  35. 35. LINQ to CQL • Then query with LINQ using the Session’s GetTable<T> method as your starting point public UserCredentials GetCredentials(string emailAddress) { IEnumerable<UserCredentials> results = _session.GetTable<UserCredentials>() .Where(uc => uc.EmailAddress == emailAddress) .Execute(); return results.SingleOrDefault(); }
  36. 36. ADO.NET Support • Available in the NuGet package as Cassandra.Data • Allows you to use your “favorite” ADO.NET objects like DbConnection, DbCommand, etc. to query Cassandra • My recommendation? Avoid it. • Cassandra concepts don’t always map well to
  37. 37. The KillrVideo Sample Application • Many of this presentation’s samples are taken from here • https://github.com/luketillman/killrvideo-csharp
  38. 38. What Next? • Data Modeling, Data Modeling, Data Modeling • Planet Cassandra (http://www.planetcassandra.org) • Links to videos, drivers, documentation, tutorials, etc. • 2.1 Beta Available (support for User Defined Types) Follow me on Twitter for updates: @LukeTillman

×