【问题标题】:C# TableEntity keeps IgnoredProperty after Insert OperationC# TableEntity 在插入操作后保持 IgnoredProperty
【发布时间】:2020-05-13 09:33:24
【问题描述】:

我有以下实现 TableEntity 的类:

public class MyEntity : TableEntity
{
    public string MyProperty { get; set; }

    [IgnoreProperty]
    public string MyIgnoredProperty { get; set; }
}

然后我有以下代码,插入一个 TableEntity:

CloudStorageAccount storageAccount = CloudStorageAccount.Parse("connectionString");
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

ITableEntity entity = new MyEntity ();
entity.RowKey = "row";
entity.PartitionKey = "partition";
entity.MyIgnoredProperty = "ignored";

CloudTable currentTable = tableClient.GetTableReference("MyEntity");
TableOperation insertOrMergeOperation = TableOperation.InsertOrMerge(entity);
TableResult result = await currentTable.ExecuteAsync(insertOrMergeOperation);
var insertedEntity = result.Result as ITableEntity;

现在奇怪的是 insertedEntity 包含 MyIgnoredProperty,尽管我希望它不应该包含它。

有人可以解释为什么它会这样吗?

顺便说一句,如果我使用以下代码显式检索实体,则 MyIgnoredProperty 也未设置在数据库中。正如预期的那样。

...
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("connectionString");
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

CloudTable currentTable = tableClient.GetTableReference(tableName);
TableOperation retrieveOperation = TableOperation.Retrieve<T>(partitionKey, rowKey);
TableResult tableResult = await currentTable.ExecuteAsync(retrieveOperation);
T result = (T)tableResult.Result;

【问题讨论】:

  • Now the strange part is that insertedEntity contains the MyIgnoredProperty, although I would expect that it shouldn't contain it. - 如果实体包含此属性,您是否检查过表存储?我的猜测是,当您反序列化实体时,它会被初始化为默认值。
  • 在 TableStorage 中没有设置属性。初始化为默认也是我最先想到的,但事实并非如此,我查了一下。它与实体具有相同的值。

标签: c# azure azure-table-storage


【解决方案1】:

也许是 ExecuteAsync 的一个问题,它返回与发送相同的对象,而不应用属性, 这是一个解决方法,是一个复制所有属性值的脚本,除了具有特定属性的值

    public static class Helper
    {
        public static MyEntity copyme(this MyEntity entity)
        {
            var copy = new MyEntity();
            var properties = typeof(MyEntity).GetProperties();

            var propertiesToExcept = typeof(MyEntity).GetProperties()
    .Where(prop => prop.IsDefined(typeof(IgnorePropertyAttribute), false));

            foreach (var prop in properties)
            {
                if (!propertiesToExcept.Any(acc => acc.Name == prop.Name))
                {
                    prop.SetValue(copy, prop.GetValue(entity));
                }
            }
            return copy;


        }
    }

为了使用它,只需调用

                var obj = new MyEntity()
                {
                    MyIgnoredProperty = "toignore",
                    MyProperty = "tokeep"
                };
                var cleanobj = obj.copyme();

【讨论】:

    【解决方案2】:

    我不是 100% 确定(因为我无法找到它的代码),但我相信这是由 SDK 完成的。

    我相信 SDK 所做的是当您插入实体时,在序列化它时通过删除标记为 IgnoreProperty 的属性来创建 JSON 有效负载。但是您的TableEntity 对象(在您的情况下为entity)仍然具有此属性。

    一旦 SDK 收到响应,它会简单地更新您的 entityETagTimestamp 属性,并在 TableResult.Result 中返回该对象。

    【讨论】:

    • 我也猜到了
    猜你喜欢
    • 2017-01-30
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 2012-04-21
    • 2015-10-05
    • 2014-10-31
    相关资源
    最近更新 更多