没有在Cassandra.Data.Linq.CqlExpressionVisitor.FillUpdateProjection上为成员结果定义映射

时间:2019-08-04 17:14:01

标签: c# cassandra asp.net-core-2.1 cassandra-3.0

我有一个带有Cassandra数据存储的基本应用程序,尝试更新实体时出现异常。

这是实体模型。

public class Log
{
    [ClusteringKey]
    public DateTime CreationDate { get; set; }
    public Guid CreatedById { get; set; }
    public DateTime? LastModifiedDate { get; set; }
    public Guid ModifiedById { get; set; }

    [Cassandra.Mapping.Attributes.PartitionKey]
    public Guid Id { get; set; } = Guid.NewGuid();
    [Cassandra.Mapping.Attributes.PartitionKey]
    public bool IsDeleted { get; set; }

    public int LoggingLevel { get; set; }
    public Guid UserId { get; set; }
    public string TimeZone { get; set; }
    public string Text { get; set; }
    public string Url { get; set; }
    [Frozen]
    public IEnumerable<LogParamsCUDT> LogParams { get; set; }
}

我如何尝试更新实体

var table = new Table<Log>(session);
var result = table.First().Execute();

以下给出的代码可以正常工作:

table.Where(w=>w.Id==result.Id && !result.IsDeleted && w.CreationDate==result.CreationDate)
.Select(s => new Log {Url="testing update" }).Update().Execute();

下面给出的代码会引发错误:

table.Where(w=>w.Id==result.Id && !result.IsDeleted && w.CreationDate==result.CreationDate)
.Select(s => result).Update().Execute();
  

InvalidOperationException:未为成员:result定义映射

我是否必须将每个属性与新对象映射,或者我做错了什么?

1 个答案:

答案 0 :(得分:1)

是的,您必须为表达式提供要更新的列的分配,因此下面是两个有效的示例:

table.Where(w=>w.Id==result.Id && !result.IsDeleted && w.CreationDate==result.CreationDate)
.Select(s => new Log {Url="testing update" }).Update().Execute();

table.Where(w=>w.Id==result.Id && !result.IsDeleted && w.CreationDate==result.CreationDate)
.Select(s => new {Url="testing update" }).Update().Execute();

我建议您使用第一个,因为如果您输错属性名称,代码甚至都不会编译。

这两个示例均导致以下准备好的语句:

UPDATE <KEYSPACE>.<TABLE> SET Url = ? WHERE Id = ? AND IsDeleted = ? AND CreationDate = ?

此外,您可能希望将!result.IsDeleted更改为w.IsDeleted == !result.IsDeleted。我相信!result.IsDeleted会因为!符号而工作,但是如果您尝试仅使用result.IsDeleted它将失败,因为驱动程序期望一个带有两个“边”的表达式(否则它将不知道将其与之进行比较)。

如果您想更新整个记录而不必指定每一列,那么我建议您查看Mapper(https://docs.datastax.com/en/developer/csharp-driver/3.11/features/components/mapper/),因为Linq2Cql当前不支持该映射器:

IMapper mapper = new Mapper(session);
mapper.Update(record);