问题的标题可能对实际情况有不同的含义 简史:
我们现有代码在azure表中执行CRUD操作。但它只能在相同的Class类型上使用InserOrMergeBatch。我需要的是一个能够添加不同类型的类的方法,只要它们具有相同的基类。 Partitionkey应该不是问题,因为它是以其他方式处理的。
所以这就是问题所在。
例如,我有两个基类:人类和动物
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#中的基本编码,对于这个问题,这是一种非常先进的编码。我完全没有想法。任何帮助,将不胜感激。
更新
我想我需要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...
}
}
答案 0 :(得分:0)
你可以像这样简单地获得基类:
Type baseClass = childClassObject.GetType().BaseType;
答案 1 :(得分:0)
如果我正确地阅读了您的问题,那么您正在寻找Interface,而不是基类(尽管可能两者都有)。
您的队列类将采用实现某个接口的对象
public class AzureTableBatchCrud
{
public void AddQueue(IQueueableObject someItem)
{
/* Must ensure that the added objects are inherited on same base class */
}
public bool ExecuteQueue()
{
/* Insert or merge objects on azure table */
return false;
}
}
您需要定义该界面:
interface IQueueableObject
{
void Queue();
}
我很难理解代码的目标。但我认为,如果你看一下界面是什么,你就会发现你可以用一种有用的方式为你的目的构建东西。