0

質問のタイトルは、実際のシナリオでは異なる意味を持つ可能性があります。
簡単な歴史:

Azure テーブルで CRUD 操作を行う既存のコードがあります。ただし、同じ Class タイプでしか InserOrMergeBatch できません。私が必要としているのは、基本クラスが同じである限り、異なるタイプのクラスを追加できるメソッドです。Partitionkey は別の方法で処理されるため、問題にはなりません。

ここに問題があります。

  1. 特定の基本クラスのキューを作成できるクラスを作成する
  2. 作成されたクラスは、必要な基本クラスを持っている限り、任意のタイプのオブジェクトを追加できる必要があります

たとえば、次の 2 つの基本クラスがあります: Human と Animal

public class Human
{
    public int Height { get; set; }
    public int Weight { get; set; }
}  

public class Animal
{
    public string Breed { get; set; }
    public string Family { get; set; }
}  

他のいくつかのクラスで使用されます:

public class Eye : Human
{
    public string Color { get; set; }
}

public class Nose : Human
{
    public string Type { get; set; }
}

public class Teeth : Human
{
    public int Count { get; set; }
}  

public class Dog : Animal
{
    public string NoseColor { get; set; }
}

public class Cat : Animal
{
    public string EyeColor { get; set; }
}  

最初の問題は、いくつかの必須メソッドを持つクラスを作成することです。

public class AzureTableBatchCrud
{

    public void CreateQueue( /* Specify the type of base class. */ )
    {
    }

    public void AddQueue( /* Accept single object or list of objects of any type */ )
    {
        /* Must ensure that the added objects are inherited on same base class */
    }

    public bool ExecuteQueue()
    {
        /* Insert or merge objects on azure table */
        return false;
    }
}  

より明確にするために、このクラスを使用してみましょう。

public class SampleUsage
{
    public void SampleInsert()
    {
        // Example 1: Creating AzureTableBatchCrud with base class 'Human'

        AzureTableBatchCrud sample1 = new AzureTableBatchCrud();
        sample1.CreateQueue(Human);

        // Right! because their base class is 'Human'
        Eye eye1 = new Eye();
        Nose nose1 = new Nose();
        Teeth teeth1 = new Teeth();

        sample1.AddQueue(eye1);
        sample1.AddQueue(nose1);
        sample1.AddQueue(teeth1);

        // Wrong! because base class is not 'Human'
        Dog dog1 = new Dog();
        Cat cat1 = new Cat();

        sample1.AddQueue(dog1); // must throw error
        sample1.AddQueue(cat1); // must throw error


        // Example 2: Creating AzureTableBatchCrud with base class 'Animal'

        AzureTableBatchCrud sample2 = new AzureTableBatchCrud();
        sample2.CreateQueue(Animal);

        // Right! because base class is 'Animal'
        Dog dog2 = new Dog();
        Cat cat3 = new Cat();

        sample2.AddQueue(dog2);
        sample2.AddQueue(cat2);

        // Wrong! because base class is not 'Animal'
        Eye eye2 = new Eye();
        Teeth teeth2 = new Teeth();

        sample2.AddQueue(eye2);     // must throw error
        sample2.AddQueue(teeth2);   // must throw error
    }
}  

例が問題の概念そのものを語っていることを願っています。

私は C# での基本的なコーディングを知っているだけで、この件に関しては、これは非常に高度なコーディングです。私は完全に考え違いです。どんな助けでも大歓迎です。

UPDATEクラス
のサンプルコードが必要だと思います。AzureTableBatchCrud

更新 2

読者が問題についてより多くのことを理解できるように、このコードを投稿しました。私はこのコードをテストしていませんが、同じ問題に遭遇した可能性のある将来の読者が参照できるように、問題が解決したらすぐに回答を投稿します。

namespace ProjectName.Domain.Entities
{
    [DataContract]
    public class NoSQLEntity: TableEntity
    {
        public NoSQLEntity()
        {
        }

        public NoSQLEntity(string partitionKey, string rowKey)
        {
            PartitionKey = partitionKey;
            RowKey = rowKey;
        }
    }
}

namespace ProjectName.Domain.Attribute
{
    [System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = false)]
    public class AzureProjectionTable: System.Attribute
    {
        public string table;
    }
}

namespace ProjectName.Data.DAOs
{
    public class CrudBatch<T> where T : NoSQLEntity
    {
        private WomContext<T> _context;
        CloudTable azuretable;
        string table;
        TableBatchOperation batchOperation;
        List<T> itemlist;

        public CrudBatch()
        {
            CloudStorageAccount storageAccount = ConfigWrapper.DataConnectionString();
            CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

            var attrs = (Domain.Attribute.AzureProjectionTable[])
                            typeof(T).GetCustomAttributes(typeof(Domain.Attribute.AzureProjectionTable), true);
            if (attrs.Length > 0)
                table = attrs[0].table;

            azuretable = tableClient.GetTableReference(table);
            _context = new WomContext<T>(tableClient, table);

            batchOperation = new TableBatchOperation();
            itemlist = new List<T>();
        }

        public void AddQueue(object item)
        {
            var attrs = (Domain.Attribute.AzureProjectionTable[])
                            item.GetType().GetCustomAttributes(typeof(Domain.Attribute.AzureProjectionTable), true);

            if (attrs.Length > 0)
            {
                if (table.Equals(attrs[0].table))
                {
                    itemlist.Add((T)item);
                }
            }
        }

        public void AddQueue(List<object> item)
        {
            foreach (var i in item)
            {
                var attrs = (Domain.Attribute.AzureProjectionTable[])
                                i.GetType().GetCustomAttributes(typeof(Domain.Attribute.AzureProjectionTable), true);

                if (attrs.Length > 0)
                {
                    if (table.Equals(attrs[0].table))
                    {
                        itemlist.Add((T)i);
                    }
                }
            }
        }

        public bool ExecuteQueue(CrudAction action)
        {
            switch (action)
            {
                case CrudAction.InsertOrMergeBatch: return InsertOrMergeBatch();
                case CrudAction.DeleteBatch: return DeleteBatch();
                default: return false;
            }
        }

        public void ClearQueue()
        {
            itemlist.Clear();
        }

        public T Get(string partitionKey, string rowKey)
        {
            TableOperation retrieve = TableOperation.Retrieve<T>(partitionKey, rowKey);
            return (T)azuretable.Execute(retrieve).Result;
        }

        public IQueryable<T> Table()
        {
            return _context.Table;
        }

        private bool InsertOrMergeBatch()
        {
            foreach (var value in itemlist)
            {
                batchOperation.InsertOrMerge(value);
            }

            azuretable.ExecuteBatch(batchOperation).ToList();

            return true;
        }

        private bool DeleteBatch()
        {
            TableBatchOperation batchOperation = new TableBatchOperation();
            T deleteEntity;

            foreach (var value in itemlist)
            {
                TableOperation retrieve = TableOperation.Retrieve<T>(value.PartitionKey, value.RowKey);
                deleteEntity = (T)azuretable.Execute(retrieve).Result;

                if (deleteEntity != null)
                {
                    batchOperation.Delete(deleteEntity);
                }
            }

            azuretable.ExecuteBatch(batchOperation);
            return true;
        }
    }

    public enum CrudAction
    {
        InsertOrMergeBatch,
        DeleteBatch
    }
}

namespace ProjectName.Data.Context
{
    public class WomContext<T> : TableServiceContext where T: NoSQLEntity
    {
        private string table;

        public WomContext(CloudTableClient client, string tablename)
            : base(client)
        {
            table = tablename;
        }

        public TableServiceQuery<T> Table
        {
            get
            {
                return this.CreateQuery<T>(table).AsTableServiceQuery(this);
            }
        }
    }
}  

サンプルの基本クラスは次のようになります。

namespace ProjectName.Domain.Entities.Carts
{
    [Attribute.AzureProjectionTable(table = BaseTableNames.Cart)]
    public class Cart: NoSQLEntity
    {
        public Cart() : base()
        {
        }

        public Cart(string partitionkey, string rowkey) 
            : base(partitionkey, rowkey)
        {
        }

        // Some properties...
    }
}
4

2 に答える 2