【问题标题】:Persisting sub-classes with DynamoDB in .NET在 .NET 中使用 DynamoDB 持久化子类
【发布时间】:2024-04-21 00:45:02
【问题描述】:

我有一个类层次结构,我想使用 DynamoDB 的 .NET 对象持久性模型(V2 条目转换)来保持它。我想将派生类保存到与基类相同的表中,然后能够查询该表中的所有条目并将它们反序列化为适当的派生类型。

在大多数 ORM 中,您将能够指定一个类型鉴别器列,它将用来决定要反序列化为哪个子类型。

代码示例:

public abstract class Animal
{
    [DynamoDBHashKey]
    public string Name { get; set; }
}

[DynamoDBTable("Animal")]
public sealed class Dog : Animal
{
    public double Loyalty { get; set; }
}

[DynamoDBTable("Animal")]
public sealed class Cat : Animal
{
    public int MiceEaten { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var client = new AmazonDynamoDBClient(RegionEndpoint.EUWest1);
        using (var context = new DynamoDBContext(client, new DynamoDBContextConfig {Conversion = DynamoDBEntryConversion.V2}))
        {
            context.Save(new Dog { Name = "Rover", Loyalty = 0.8 });
            context.Save(new Cat { Name = "Felix", MiceEaten = 14 });

            var doggie = context.Load<Animal>("Rover");
            var pussy = context.Load<Animal>("Felix");

            Console.WriteLine(doggie.GetType().Name); // should output Dog
            Console.WriteLine(pussy.GetType().Name); // should output Cat
        }
    }
}

预期的输出是:

Dog
Cat

但实际上崩溃了以下异常:

Unhandled Exception: System.InvalidOperationException: 
Type ConsoleApplication1.Animal is unsupported, it cannot be instantiated

有没有一种很好的方法来保持这个类层次结构?如果需要,我可以对类模型进行更改,我只是希望它感觉像惯用的 C#。

我还尝试了将 DynamoDBTable 属性放在何处的各种组合,包括仅在 Animal 和所有三个类上。如果我从 Animal 中删除抽象,它不会抛出异常,而是输出 Animal Animal,因此不会反序列化特定于派生类的属性。

【问题讨论】:

    标签: c# .net amazon-dynamodb aws-sdk


    【解决方案1】:

    我现在遇到了同样的问题。据我所知,DynamoDB 没有为将行数据从单个表映射到不同的 C# 类提供一流的支持。

    GitHub aws-sdk-net 存储库 (#245) 中发布了一个问题,该问题显示了如何使用类型鉴别器方法将表行反序列化为不同的 C# 类。这就是我要开始调查的内容……如果成功了,我会在这里更新我的答案。

    更新 #1:不幸的是,将 DynamoDB 数据反序列化为适当的子类类型的唯一方法似乎是类型映射——也就是说,构建一组类型检查,将您的 DynamoDB 转换为匹配具体类型。

    【讨论】: