Azure Table Storage的批处理器,用于处理继承TableEntity的类

时间:2016-12-09 16:48:16

标签: c# azure azure-table-storage

我有许多不同的Azure表,我想写一些具有一些核心属性和一些不同的属性。我想分批编写以最大限度地降低成本,但我很难在处理器功能中获得正确的类型以促进这一点。

应该使用哪些类型或附加代码来使此函数处理示例类?

批处理代码和repro

using System;
using System.Collections.Generic;
using Microsoft.WindowsAzure.Storage.Table;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
    }

    static void BatchInsertOrReplace<ITableEntity>(List<ITableEntity> items, CloudTable table)
    {
        // setup
        List<ITableEntity> batch = new List<T>();
        TableBatchOperation batchOperation = new TableBatchOperation();
        // n-1 batches
        foreach (var item in items)
        {
            batch.Add(item);
            batchOperation.InsertOrReplace(item);
            if (batch.Count == 100)
            {
                table.ExecuteBatch(batchOperation);
                batchOperation.Clear();
                batch.Clear();
            }
        }

        // nth batch
        if (batch.Any())
        {
            table.ExecuteBatch(batchOperation);
        }
    }

    // things I want to be able to push to table storage
    public class exampleClass : TableEntity
    {
        public DateTime rawDate { get; set; }
    }

    public class exampleClass_deriv1 : exampleClass
    {
        public string User { get; set; }
        public string Device { get; set; }
    }

    public class exampleClass_deriv2 : exampleClass
    {
        public string Person { get; set; }
        public string Machine { get; set; }
    }
}

样本用法

我正在从Azure表存储中检索实体并当前转换它们的代码:

IEnumerable<exampleClass> recs = (from r in mytable
                                   where r.rawDate >= DateTime.Now
                                   select r);
var recsaccount = recs
    .Select(r => new exampleClass_deriv1
    {
        PartitionKey = r.PartitionKey,
        RowKey = r.RowKey,
        rawDate = r.rawDate,
        epochDate = i.epochDate,
        User = "Jim",
        Device = "Palmpilot"
    });
// Desired execution (which errors)
BatchInsertOrReplace(recsaccount.ToList(), mytable);

(List<ITableEntity>)recsaccount.ToList()这样的简单强制不起作用

run.csx(63,30): error CS0030: Cannot convert type 'System.Collections.Generic.List<exampleClass_deriv2>' to 'System.Collections.Generic.List<ITableEntity>'

更新1

制作新的清单并首先将物品放入其中:

List<ITableEntity> ins = new List<ITableEntity>();
foreach (var blah in recs.ToList())
{
   ITableEntity newOne = (ITableEntity)blah;
    ins.Add(newOne);
}
BatchInsertOrReplace(ins, mytable);

导致错误如:

error CS0411: The type arguments for method 'BatchInsertOrReplace<T>(List<ITableEntity>, CloudTable)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

尝试使用类型前缀并没有改变这种情况。

更新2 - 使用<T>

如果我在函数定义中使用<T>,如

static void BatchInsertOrReplace<T>(List<T> items, CloudTable table)
{
    List<T> batch = new List<T>(); // Alt of List<ITableEntity> batch = new List<ITableEntity>(); 
    TableBatchOperation batchOperation = new TableBatchOperation();
    foreach (var item in items)
    {
        batch.Add(item);
        batchOperation.InsertOrReplace(item);

        if (batch.Count == 100)
        {
            table.ExecuteBatch(batchOperation);
            batchOperation.Clear();
            batch.Clear();
        }
    }

    // Process last batch
    if (batch.Any())
    {
        table.ExecuteBatch(batchOperation);
    }
}

然后使用类似的功能 BatchInsertOrReplace<exampleClass_deriv2>( recsaccount.ToList(), webhitsAggAccount);会生成关于batch.AddbatchOperation.InsertOrReplace

的消息
run.csx(128,19): error CS1503: Argument 1: cannot convert from 'T' to 'Microsoft.WindowsAzure.Storage.Table.ITableEntity'
run.csx(129,40): error CS1503: Argument 1: cannot convert from 'T' to 'Microsoft.WindowsAzure.Storage.Table.ITableEntity'

无论batchList<ITableEntity>还是List<T>,都会发生这种情况。

1 个答案:

答案 0 :(得分:1)

您应该确保函数定义允许变量类型使其签名使用T,但声明T继承ITableEntity。这可以使用where子句作为函数的第一个声明的一部分来完成。您的批处理功能将变为:

static void BatchInsertOrReplace<T>(List<T> items, CloudTable table) where T : ITableEntity
{
    List<ITableEntity> batch = new List<ITableEntity>();
    TableBatchOperation batchOperation = new TableBatchOperation();
    foreach (var item in items)
    {
        batch.Add(item);
        batchOperation.InsertOrReplace(item);

        if (batch.Count == 100)
        {
            table.ExecuteBatch(batchOperation);
            batchOperation.Clear();
            batch.Clear();
        }
    }

    // Process last batch
    if (batch.Any())
    {
        table.ExecuteBatch(batchOperation);
    }
}