5

I am a newbie to Cassandra and created a generic repository for my Cassandra database using linq. For my Single() method, I am passing the where criteria as a parameter.

This is my Single method:

Single(Expression<Func<T, bool>> exp)

This is the linq code I am using to query the cassandra database

public async Task<T> Single(Expression<Func<T, bool>> exp)
{
    return await GetTable.Where<T>(exp).FirstOrDefault().ExecuteAsync();
}

This is the method calling the single method

public override Task OnConnected()
{
    if (Context.User != null)
    {
        string userName = Context.User.Identity.Name;

        this.Groups.Add(userName, Context.ConnectionId);

        ***** this is the line with the issue ******
        Notification notification = Task.Run(() => _notificationRepository.Single(x => x.UserName.Equals(userName))).Result;

        if (notification == null)
        {
            _notificationRepository.CreateInstance(new NotificationUserMapping { Connections = new string[] { Context.ConnectionId }, UserName = Context.User.Identity.Name });
        }
        else if (!notification.Connections.Contains(Context.ConnectionId))
        {
            notification.Connections.Add(Context.ConnectionId);
            _notificationRepository.Save(notification);
        }
    }

    return base.OnConnected();
}

I keep getting a "System.AggregateException" of "Argument types do not match" and I am confused about where this could be coming from.

The database table columns:

id uuid PRIMARY KEY,
connections list<text>,
username text

and the c# poco:

[Table(ExplicitColumns = true)]
public class ConnectionMapping
{
    [Column("id")]
    public Guid Id { get; set; }
    [Column("connections")]
    public IList<string> Connections { get; set; }
    [Column("username")]
    public string UserName { get; set; }
}

and the exception:

   at System.Linq.Expressions.Expression.Condition(Expression test, Expression ifTrue, Expression ifFalse)
   at Cassandra.Mapping.MapperFactory.GetExpressionToGetColumnValueFromRow(ParameterExpression row, CqlColumn dbColumn, Type pocoDestType)
   at Cassandra.Mapping.MapperFactory.CreateMapperForPoco[T](RowSet rows, PocoData pocoData)
   at Cassandra.Mapping.MapperFactory.CreateMapper[T](RowSet rows)
   at Cassandra.Mapping.MapperFactory.<>c__DisplayClass1`1.<GetMapper>b__0(Tuple`2 _)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Cassandra.Mapping.MapperFactory.GetMapper[T](String cql, RowSet rows)
   at Cassandra.Mapping.Mapper.<>c__DisplayClass7`1.<FetchAsync>b__6(Statement s, RowSet rs)
   at Cassandra.Mapping.Mapper.<>c__DisplayClass2`1.<>c__DisplayClass4.<ExecuteAsyncAndAdapt>b__1(Task`1 t2)
   at Cassandra.Tasks.TaskHelper.DoNext[TIn,TOut](Task`1 task, Func`2 next)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at CompanyNamespace.CompanyDomain.NotificationRepository.<SingleByUserName>d__0.MoveNext()

What am I missing. I reveiwed the docs. and the mapping rules between Cassandra and c# and everything seems correct.

Community
  • 1
  • 1
user1790300
  • 2,143
  • 10
  • 54
  • 123
  • Can you show the whole method? It's hard to tell when you just provide tiny snippets. – DavidG Aug 05 '16 at 16:19
  • Could you also add the stack trace for the exception that's inside the `AggregateException` you're receiving? Might point us in the right direction. – Luke Tillman Aug 06 '16 at 18:29

1 Answers1

5

Through some experimentation, I found the answer. Come to find out Cassandra List-based collections do not map to c# lists, it map to c# IEnumerable objects instead.

user1790300
  • 2,143
  • 10
  • 54
  • 123
  • I experimented with CassandraCSharpDriver v3.11 and it turns out that the type mapping works if you are using array, IEnumerable, ICollection or IReadOnlyList but for some reason not IList. It is surprising that the driver doesn't map everything implementing IEnumerable to a Cassandra list – scharnyw Sep 03 '19 at 05:33