Cassanda可以在查询中聚合LINQ表达式吗?



我对Cassandra很陌生,所以我有一个问题我找不到答案。在EF Core中,我可以将LINQ表达式列表作为条件传递并汇总它们,以便我可以找到我需要的内容,例如:

public async Task<IEnumerable<string>> GetDataStream(List<Expression<Func<Model, bool>>> predicates)
{
var query = _context.Model.AsQueryable();
if (predicates != null)
{
query = predicates.Aggregate(query, (@event, condition) => @event.Where(condition));
}
return await query.Select(data => data.).ToListAsync();
} 

现在我想知道Cassandra是否有这样的可能性。我试着:

public async Task<IEnumerable<Model>> Find(List<Expression<Func<Model, bool>>> predicates, int assetId)
{
IQueryable<Model> query = _table.AsQueryable();
if (predicates != null)
{
query = predicates.Aggregate(query, (@event, condition) => @event.Where(condition));
}
return await query.Select(data => data); // here is a problem dont know ow to execute this
}

那么这样的事情可能吗?

编辑:

所以我尝试了聚合组合

查询。选择(d =比;

d) . execute ();也在result

中得到这个异常

表达式Call= [SELECT gap_end, gap_start, uuid FROM gaps_state_data.](数据=比;(数据。EndValue == null))]None解析阶段不支持。

由于某些原因,看起来表达式聚合没有被格式化。

我相信这就是你要找的:

public static async Task<IEnumerable<Model>> Find(Table<Model> table, List<Expression<Func<Model, bool>>> predicates)
{
CqlQuery<Model> query = table;
if (predicates != null)
{
query = predicates.Aggregate(query, (@event, condition) => @event.Where(condition));
}
return await query.ExecuteAsync();
}

这与你的答案基本相同,但你实际上不需要.Select()部分,你只需要将表转换为CqlQuery<Model>对象。

下面是我用来测试这一点的完整示例(请记住,这个代码片段创建并删除了一个键空间和表):
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Threading.Tasks;
using Cassandra;
using Cassandra.Data.Linq;
using Cassandra.Mapping.Attributes;
using Exception = System.Exception;
namespace OssSandbox
{
public class ProgramLinq
{
public static void Main(string[] args)
{
Cassandra.Diagnostics.CassandraTraceSwitch.Level = TraceLevel.Info;
Trace.AutoFlush = true;
using var cluster = Cassandra.Cluster.Builder()
.AddContactPoint(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9042))
.Build();
using var session = cluster.Connect();
session.CreateKeyspaceIfNotExists("ks1", new Dictionary<string, string> { { "class", "SimpleStrategy"}, { "replication_factor", "1"} });
var table = new Table<Model>(session);
session.Execute("DROP TABLE IF EXISTS ks1.Model");
table.CreateIfNotExists();
table.Insert(new Model { Id = 1, Value1 = "1", Value2 = "2", Value3 = "3" }).Execute();
table.Insert(new Model { Id = 1, Value1 = "1", Value2 = "2", Value3 = "23" }).Execute();
table.Insert(new Model { Id = 1, Value1 = "1", Value2 = "22", Value3 = "23" }).Execute();
table.Insert(new Model { Id = 1, Value1 = "21", Value2 = "22", Value3 = "23" }).Execute();
table.Insert(new Model { Id = 1, Value1 = "31", Value2 = "32", Value3 = "33" }).Execute();
table.Insert(new Model { Id = 1, Value1 = "41", Value2 = "42", Value3 = "43" }).Execute();
table.Insert(new Model { Id = 2, Value1 = "221", Value2 = "222", Value3 = "223" }).Execute();
var results1 = Find(table, new List<Expression<Func<Model, bool>>>
{
m => m.Id == 1,
m => m.Value1 == "1",
m => m.Value2 == "2",
}).GetAwaiter().GetResult();
PrintRowsResult(results1, "Id == 1 && Value1 == 1 && Value2 == 2");
}
public static void PrintRowsResult(IEnumerable<Model> results, string query)
{
Console.WriteLine();
Console.WriteLine(query);
Console.WriteLine();
try
{
Console.WriteLine();
foreach (var row in results)
{
Console.WriteLine("Id: " + row.Id);
Console.WriteLine("Value1: " + row.Value1);
Console.WriteLine("Value2: " + row.Value2);
Console.WriteLine("Value3: " + row.Value3);
Console.WriteLine();
}
}
catch (Exception ex)
{
Console.WriteLine();
Console.WriteLine("####### ERROR: " + ex.Message);
Console.WriteLine();
}
}
public static async Task<IEnumerable<Model>> Find(Table<Model> table, List<Expression<Func<Model, bool>>> predicates)
{
CqlQuery<Model> query = table;
if (predicates != null)
{
query = predicates.Aggregate(query, (@event, condition) => @event.Where(condition));
}
Console.WriteLine(query.ToString()); // just for debug purposes
return await query.ExecuteAsync();
}
[Cassandra.Mapping.Attributes.Table(Keyspace = "ks1")]
public class Model
{
[Cassandra.Mapping.Attributes.PartitionKey]
public int Id { get; set; }
[Cassandra.Mapping.Attributes.ClusteringKey(0)]
public string Value1 { get; set; }
[Cassandra.Mapping.Attributes.ClusteringKey(1)]
public string Value2 { get; set; }
[Cassandra.Mapping.Attributes.ClusteringKey(2)]
public string Value3 { get; set; }
}
}
}

好了,我找到了这个,在注释中使用提示,让我展示它的完整代码以及它应该如何工作:

public Task<IEnumerable<Model>> Find(List<Expression<Func<Model, bool>>> predicates)
{
CqlQuery<Model> query = _table.Select(d => d);
if (predicates != null)
{
query = predicates.Aggregate(query, (@event, condition) => @event.Where(condition));
}
return query.ExecuteAsync();
}

因为我需要用IQueryable替换表类型,但是当我这样做的时候,像_table.AsQueryable()选择表达式编译自己。所以我需要启动表达式,将表更改为IQueryable,这是Select()的角色。之后我可以从参数中添加表达式。

最新更新