簡體   English   中英

Azure 存儲表 - 並非 TableEntity 的所有屬性都在 InsertOperation 之后存儲

[英]Azure Storage Tables - Not all properties from TableEntity are being stored after InsertOperation

所以問題是:我有一個實體,它有 40 個屬性(都在代碼中正確定義為“public String PropertyName {get;set;}”。當我插入新實體時,大部分屬性都被存儲,但其中一些不是。

代碼如下:

public class PostTableEntity : TableEntity
{
    #region Fields
    #endregion

    #region Properties
    public Guid CreatorId { get; set; }
    public String HtmlText { get; set; }
    public String SubjectIds { get; set; }
    public String QuoteString { get; set; }
    public double GeoLat { get; set; }
    public double GeoLong { get; set; }
    public String GeoPlace { get; set; }
    public Int32 TotalSmiles { get; set; }
    public DateTime DateUTC { get; set; }
    public Guid? EventId { get; set; }
    public string EventName { get; set; }
    public String ExcludedUsers { get; set; }
    public String Comment00_Text { get; set; }
    public Guid Comment00_UserId { get; set; }
    public Guid Comment00_CommentId { get; set; }
    {...} //Some more props - no more than 30 in total        
    public String VeryImportantData { get; set; }
    #endregion

    #region Constructors
    public PostTableEntity()
    {

    }

    public PostTableEntity(String partitionKey, String rowKey, Guid creatorId, DateTime dateUTC, String htmlText)
        : base(partitionKey, rowKey)
    {
        this.CreatorId = creatorId;
        this.HtmlText = htmlText;
        this.DateUTC = dateUTC;
    }
    #endregion

    #region Methods
    public void SetSubjectIdsList(List<Guid> subjectIds)
    {
        if (subjectIds != null)
        {
            this.SubjectIds = String.Join(";", subjectIds);
        }
        else
        {
            this.SubjectIds = "";
        }
    }
    #endregion
}

...然后有一個派生類:

public class ImagePostTableEntity : PostTableEntity
{
    #region Fields
    #endregion

    #region Properties
    public String StorageAccountName { get; set; }
    public String StorageContainerName { get; set; }
    public String BlobName_Original { get; set; }
    public String BlobName_Large { get; set; }
    public String BlobName_Medium { get; set; }
    public String BlobName_Small { get; set; }      
    #endregion

    #region Constructors
    public ImagePostTableEntity()
    {

    }

    public ImagePostTableEntity(String partitionKey, String rowKey, Guid creatorId, DateTime date, String htmlText, List<Guid> subjectIds, String storageAccountName, String storageContainerName, String blobName_Original, String blobName_Large, String blobName_Medium, String blobName_Small)
        : base(partitionKey, rowKey, creatorId, date, htmlText)
    {            
        this.StorageAccountName = storageAccountName;
        this.StorageContainerName = storageContainerName;            

        this.BlobName_Original = blobName_Original;
        this.BlobName_Large = blobName_Large;
        this.BlobName_Medium = blobName_Medium;
        this.BlobName_Small = blobName_Small;

        this.SetSubjectIdsList(subjectIds);
    }
}

所以我這樣稱呼 InsertOperation(我認為沒什么特別的):

 ImagePostTableEntity newPost = new ImagePostTableEntity(streamId.ToString(), newPostId.ToString(), creatorId, date, htmlText, subjectIds, storageAccountName, storageContainerName, blobName_Original, blobName_Large, blobName_Medium, blobName_Small); //This construcotr calls inner method: SetSubjectIdsList(subjectIds);
            newPost.TotalComments = 0;
            newPost.VeryImportantData = "That very important string";
            TableOperation insertOperation = TableOperation.Insert(newPost);

此操作后,表存儲中存在實體,但未存儲某些屬性。 具體而言,僅不存儲“SubjectIds”和“VeryImportantData”。 它們不為空,並且具有一定的價值(仔細檢查 ;))

除了艾米麗(Emily)提到的沒有執行方法的內容外,我沒有看到您在其中設置subjectIds值的代碼。 艾米麗(Emily)提出的另一個好處是,您如何驗證該實體不具有那些屬性?

嘗試使用提琴手來確保確實發送了一些東西。

我很確定您之前看過此指南 ,但請再次查看以確保您沒有遺漏任何內容。

請記住,在執行插入操作時,如果該表中已經存在具有相同PK和RK的實體,則不會插入該實體。 InsertOrReplace操作將允許您執行此操作。

您在保存時遇到問題或保存后缺少屬性的天氣。 首先要注意的是TableOperation.Insert方法本身。 通過檢查其參數,很明顯它接受Microsoft.Azure.Cosmos.Table.ITableEntity類型的參數。 這意味着如果您傳遞任何對象,它將自動轉換為該接口,當然,只要該對象來自實現該接口的類。

namespace Microsoft.WindowsAzure.Storage.Table
{
    public interface ITableEntity
    {
        string PartitionKey { get; set; }
        string RowKey { get; set; }
        DateTimeOffset Timestamp { get; set; }
        string ETag { get; set; }

        void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext);
        IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext);
    }
}

通過檢查這個接口成員,我確定這兩個屬性(PartitionKey,RowKey)是必需的,應該在進入數據庫之前進行初始化

並且為了通知運行時您的對象中的額外自定義成員,該接口有一個WriteEntity函數。 此函數在內部用於返回具有對象中所有屬性的集合。

幸運的是或由於最佳實踐, TableEntity類將其實現WriteEntity使用 virtual 的WriteEntity ,因此任何派生類都可以從覆蓋它並添加所需的屬性中受益

namespace Microsoft.WindowsAzure.Storage.Table
{
    public class TableEntity : ITableEntity
    {
        public TableEntity();
        public TableEntity(string partitionKey, string rowKey);

        public string PartitionKey { get; set; }
        public string RowKey { get; set; }
        public DateTimeOffset Timestamp { get; set; }
        public string ETag { get; set; }

        public static TResult ConvertBack<TResult>(IDictionary<string, EntityProperty> properties, OperationContext operationContext);
        public static TResult ConvertBack<TResult>(IDictionary<string, EntityProperty> properties, EntityPropertyConverterOptions entityPropertyConverterOptions, OperationContext operationContext);
        public static IDictionary<string, EntityProperty> Flatten(object entity, OperationContext operationContext);
        public static IDictionary<string, EntityProperty> Flatten(object entity, EntityPropertyConverterOptions entityPropertyConverterOptions, OperationContext operationContext);
        public static void ReadUserObject(object entity, IDictionary<string, EntityProperty> properties, OperationContext operationContext);
        public static IDictionary<string, EntityProperty> WriteUserObject(object entity, OperationContext operationContext);
        public virtual void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext);
        public virtual IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext);
    }
}

我做了一個樣品給你。 確保硬編碼值將是動態的,並將根據您的應用程序中的某些邏輯進行計算

public class CustomClass : TableEntity
{
    public CustomClass()
    {
        RowKey = Guid.NewGuid().ToString();
        PartitionKey = DateTime.Today.ToString("yyyy-MM");
        Timestamp = DateTime.Now;
        ETag = "*";
    }

    public CustomClass(string id, string name, bool? vip) : this()
    {
        Id = id;
        Name = name;
        VIP = vip;
    }

    public string Id { get; set; }

    public string Name { get; set; }

    public bool? VIP { get; set; }

    public override IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext)
    {
        return new Dictionary<string, EntityProperty>() {
            {nameof(Id), new EntityProperty(Id) },
            {nameof(Name), new EntityProperty(Name) },
            {nameof(VIP), new EntityProperty(VIP) },
            {nameof(RowKey), new EntityProperty(RowKey) },
            {nameof(Timestamp), new EntityProperty(Timestamp) },
            {nameof(ETag), new EntityProperty(ETag) },
            {nameof(PartitionKey), new EntityProperty(PartitionKey) }
        };
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM